Search code examples
bashhttp-redirectoperator-keyword

How to delay `redirection operator` of BASH `>`


First I create 3 files:

$ touch alpha bravo carlos

Then I want to save the list to a file:

$ ls > info.txt

However, I always got my info.txt inside:

$ cat info.txt
alpha
bravo
carlos
info.txt

It looks like the redirection operator creates my info.txt first.

In this case, my question is. How can I save my list of files before creating the info.txt first?


The main question is about the redirection operator. Why does it act first, and how to delay it so I complete my task first? Using the example above to answer it.


Solution

  • When you redirect a command's output to a file, the shell opens a file handle to the destination file, then runs the command in a child process whose standard output is connected to this file handle. There is no way to change this order, but you can redirect to a file in a different directory if you don't want the ls output to include the new file.

    ls >/tmp/info.txt
    mv /tmp/info.txt ./
    

    In a production script, you should make sure that the file name is unique and unpredictable.

    t=$(mktemp -t lstemp.XXXXXXXXXX) || exit
    trap 'rm -f "$t"' INT HUP 
    ls >"$t"
    mv "$t" ./info.txt
    

    Alternatively, capture the output into a variable, and then write that variable to a file.

    files=$(ls)
    echo "$files" >info.txt
    

    As an aside, probably don't use ls in scripts. If you want a list of files in the current directory

    printf '%s\n' *
    

    does that.