Overview¶
There are quite a few resources online on Bash scripting which are extremely useful. I particularly recommend Awesome Bash and The Art of Command Line. There is little point writing yet another Bash tutorial, however, I’d like to share a few helpful notes which others who just start using a command line may find useful.
Multiple arguments to the same command¶
Many Unix commands accept multiple arguments, one after another:
$ ls *.jar *.vsix
tmp-142zodmSW1YLvRv.vsix tmp-417e1PTGYuSLOnV.vsix winstone10385665803316081333.jar
tmp-192iFDUu55RqcPk.vsix tmp-417qbhJlHnXzkZl.vsix winstone4439219046698760640.jar
tmp-31894bwaoyq9zL7em.vsix tmp-549k8JeuzrFyHMC.vsix winstone4470366079702491377.jar
$ touch foo.bar foo.baz
$ ls foo.*
foo.bar foo.baz
One line for
loop¶
It’s common to see a for
loop that spans over multiple lines in shell scripts:
for jarfile in *.jar;
do file ${jarfile};
done
However, working with the for
loop spanning over multiple lines in terminal
can be cumbersome.
Fortunately, the for
loop can be put into a single line:
$ for jarfile in *.jar; do file ${jarfile}; done
winstone10385665803316081333.jar: Java archive data (JAR)
winstone4439219046698760640.jar: Java archive data (JAR)
winstone4470366079702491377.jar: Java archive data (JAR)
Reading standard input¶
Some programs are limited and may not accept files as input arguments. Another use case is when you have to pass sensitive data such as passwords as input to programs using a command line interface (so that it doesn’t end up in the terminal history).
For example, you may need to produce a semicolon separated list of files (and some program has already produced a list of files):
$ cat files.txt
winstone10385665803316081333.jar
winstone4439219046698760640.jar
winstone4470366079702491377.jar
$ tr '\n' ';' < files.txt
winstone10385665803316081333.jar;winstone4439219046698760640.jar;winstone4470366079702491377.jar;%
Submit multiline input to a command¶
When you need to supply a multiline input to a command, particularly if this needs to happen interactively, you can use a here document which can be used within a shell script file or at a prompt:
$ tr '[:lower:]' '[:upper:]' << END
first line
and second line
and third line
END
FIRST LINE
AND SECOND LINE
AND THIRD LINE
Another useful feature is to be able to write multiline input to a file. This can be very handy when you have to create a multiline file (potentially with non trivial indentation) and the machine you are connected to does not have any text editors available.
$ cat << EOF > dummy.txt
The file contents to be written: line 1
and line 2
EOF
$ cat dummy.txt
The file contents to be written: line 1
and line 2
Single and double quotes¶
Single quotes do not let filename and variable expansion to happen in the quoted text. Be very careful mixing the single and double quotes!
$ export SITE_TOKEN='mytoken'
$ echo "$SITE_TOKEN"
mytoken
$ echo '$SITE_TOKEN'
$SITE_TOKEN
Grouping commands and values using curly braces¶
It can be very useful to be able to run multiple commands, one after another, and save the output to a file. This would let you avoid having multiple lines in your script (where each line would be appending to the file). For instance, to create a log of some system operation:
$ { date; whoami; echo "----"; ls /var } > log$(date '+%Y-%m-%d').txt
$ head -n 5 log2020-12-15.txt
Tue Dec 15 22:21:59 GMT 2020
username
----
backups
cache
crash
Happy shelling!