How to find next available file descriptor in Bash?

前端 未结 5 2129
离开以前
离开以前 2020-12-15 11:40

How can I figure out if a file descriptor is currently in use in Bash? For example, if I have a script that reads, writes, and closes fd 3, e.g.

exec 3<          


        
5条回答
  •  遥遥无期
    2020-12-15 12:28

    In pure bash, you can use the following method to see if a given file descriptor (3 in this case) is available:

    rco="$(true 2>/dev/null >&3; echo $?)"
    rci="$(true 2>/dev/null <&3; echo $?)"
    if [[ "${rco}${rci}" = "11" ]] ; then
        echo "Cannot read or write fd 3, hence okay to use"
    fi
    

    This basically works by testing whether you can read or write to the given file handle. Assuming you can do neither, it's probably okay to use.

    In terms of finding the first free descriptor, you can use something like:

    exec 3>/dev/null    # Testing, comment out to make
    exec 4

    Running that script gives 5 as the first free descriptor but you can play around with the exec lines to see how making an earlier one available will allow the code snippet to find it.


    As pointed out in the comments, systems that provide procfs (the /proc file system) have another way in which they can detect free descriptors. The /proc/PID/fd directory will contain an entry for each open file descriptor as follows:

    pax> ls -1 /proc/$$/fd
    0
    1
    2
    255
    

    So you could use a script similar to the one above to find a free entry in there:

    exec 3>/dev/null    # Testing, comment out to make
    exec 4

    Just keep in mind that not all systems providing bash will necessarily have procfs (the BDSs and CygWin being examples). Should be fine for Linux if that's the OS you're targeting.


    Of course, you do still have the option of wrapping your entire shell script as something like:

    (
        # Your current script goes here
    )
    

    In that case, the file handles will be preserved outside those parentheses and you can manipulate them within as you see fit.

提交回复
热议问题