1

I'm using cat to create a new file via a shell script. It looks something like:

./script.sh > output.txt

How can I access output.txt as a variable in my script. I've tried $1 but that doesn't work.

The script looks something like:

#!/bin/sh

cat  << EOF
echo "stuff"
EOF

Since there doesn't apear to be an os-agnostic way to do this, is there a way I pass the output into the script as an argument and then save the cat results to a file inside the script?

So the command would look like: ./script.sh output.txt and I can access the output as $1. Is something like this possible?

8
  • Can you show the code of your script.sh? Commented Mar 9, 2018 at 18:36
  • In a completely OS-agnostic way, you can't. There are linuxisms, but they're, well, Linuxisms. Commented Mar 9, 2018 at 18:37
  • Posted the basics of the script Commented Mar 9, 2018 at 18:37
  • If you run ./script.sh output.txt, then output.txt is automatically $1. What's the question, at that point? (Is it how to make your output go to that file, for the rest of the script? Put exec >"$1" up top). Commented Mar 9, 2018 at 18:40
  • BTW, #!/bin/sh is not bash -- they're two different shells, and aren't compatible with each other (bash isn't even quite a proper superset -- its echo is subtly incompatible with the POSIX sh standard, which doesn't permit echo -e to do anything but print -e as text on stdout). If that's the shebang you're using, you should use the sh tag, not the bash tag. Commented Mar 9, 2018 at 18:42

2 Answers 2

5

The Literal Question: Determining Where Your Stdout Was Redirected To

When a user runs:

./yourscript >outfile

...they're telling their shell to open outfile for write, and connect it to the stdout of your script, before starting your script. Consequently, all the operations on the filename are already finished when your script is started, so the name isn't passed to the script directly.

On Linux (only), you can access the location to which your stdout was redirected before your script was started through procfs:

output_dest=$(readlink -f /dev/fd/1)

echo "My output is being written to $output_dest"

This is literally interrogating where your first file descriptor (which is stdout) is open to. Note that the results won't always be useful -- if your program is being piped into something else, for instance, it might be something like [pipe: 12345].

If you care about portability or robustness, you should generally write your software in such a way that it doesn't need to know or care where its stdout is being directed.


The Best Practice: Redirecting Your Script's Stdout Yourself

Better practice, if you need an output filename that your script can access, is to accept that as an explicit argument:

#!/bin/sh
#      ^^ note that that makes this a POSIX sh script, not a bash script

outfile=$1

exec >"$outfile"  # all commands below here have their output written to outfile

cat >>EOF
This is written to $outfile
EOF

...and then directing the user to pass the filename as an argument:

./yourscript outfile
Sign up to request clarification or add additional context in comments.

Comments

1
#!/bin/sh
outfile=$1
cat  << EOF > "$outfile"
echo "stuff"
EOF

With

./script.sh output.txt

You write to the file output.txt

Setting a default value, in case the user doesn't pass an argument, is left for a different question.

4 Comments

cat << EOF >> "$outfile" ?
>> "$outfile", in that case -- quotes matter.
By the way why not just >>"$1"...?
@GeorgeVasiliou: Just a habit which pays of in longer scripts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.