Pipe Bash command output to stdout and to a variable

后端 未结 1 1803
隐瞒了意图╮
隐瞒了意图╮ 2020-12-20 03:25

I have to find files with selected permissions and list them as well as their number. Therefore I would like to pipe result of find command to shell and to the

相关标签:
1条回答
  • 2020-12-20 03:46

    Copying To A TTY (Not Stdout!)

    Pipeline components run in subshells, so even if they do assign shell variables (and the syntax for that was wrong), those shell variables are unset as soon as the pipeline exits (since the subshells only live as long as the pipeline does).

    Thus, you need to capture the output of the entire pipeline into your variable:

    var=$(find "$filename" -perm "$i" | tee /dev/tty | wc -l)
    

    Personally, btw, I'd be teeing to /dev/stderr or /dev/fd/2 to avoid making behavior dependent on whether a TTY is available.


    Actually Piping To Stdout

    With bash 4.1, automatic file descriptor allocation lets you do the following:

    exec {stdout_copy}>&1 # make the FD named in "$stdout_copy" a copy of FD 1
    
    # tee over to "/dev/fd/$stdout_copy"
    var=$(find "$filename" -perm "$i" | tee /dev/fd/"$stdout_copy" | wc -l)
    
    exec {stdout_copy}>&- # close that copy previously created
    echo "Captured value of var: $var"
    

    With an older version of bash, you'd need to allocate a FD yourself -- in the below example, I'm choosing file descriptor number 3 (as 0, 1 and 2 are reserved for stdin, stdout and stderr, respectively):

    exec 3>&1  # make copy of stdout
    
    # tee to that copy with FD 1 going to wc in the pipe
    var=$(find "$filename" -perm "$i" | tee /dev/fd/3 | wc -l)
    
    exec 3>&-  # close copy of stdout
    
    0 讨论(0)
提交回复
热议问题