Bash General
There is an important difference between Bash and POSIX Shell. The commands:
$ grep root /etc/passwd | IFS=: read -r user x1 uid gid x2 home shell $ echo $uid $home
do not produce the desired output. The read
command
runs in a subshell and the values it reads are lost when we come to
the echo
command. Solutions to this problem are as
follows:
$ { IFS=: read -r user x1 uid gid x2 home shell ; } <<EOS $(grep root /etc/passwd) EOS
or simply
$ IFS=: read -r user x1 uid gid x2 home shell <<<$(grep root /etc/passwd)
or using process substitution (see below)
$ IFS=: read -r user x1 uid gid x2 home shell < <(grep root /etc/passwd)
To process multiple lines you can use this:
$ while IFS=: read -r user x1 uid gid x2 home shell ; do echo $uid $home done < /etc/passwd
The command
$ command &>filename
redirects both the stdout and the stderr of
command
to filename
. Use
&>>
for appending.
Use the -e
option with echo
to
print escaped characters. For example,
$ echo -e "\v\v\v\v"
prints vertical tabs.
The tab character is usually used for command completion in Bash.
So, you cannot type in a tab character using the Tab
key in command line. Use Ctrl+V and
then the Tab key. That will put a literal tab character
on the command line, which can be useful if you need to
grep
a tab in a tab-delimited text file,
for example.
The /dev/urandom
device-file provides a means of
generating much more random
pseudorandom numbers than the
$RANDOM
variable.
To do random I/O in Bash, in other words to write at a specified place in a file, use something like in the following example:
$ echo 1234567890 >File # Write string to "File" $ exec 3<> File # Open "File" and assign fd 3 to it $ read -n 4 <&3 # Read only 4 characters $ echo -n . >&3 # Write a decimal point there (on 5th character) $ exec 3>&- # Close fd 3 $ cat File # will return "1234.67890"
You can use process substitution to eliminate the need of saving intermediate command outputs to temporary files. For example, to compare the contents of two directories (to see which filenames are in one, but not the other) execute
$ diff <(ls first_directory) <(ls second_directory)
You can use the special device directory
/dev/tcp/
in
Bash to do socket I/O. For example, to get current time from a time server
(e.g. time.nist.gov) using daytime
port (13) run:
$ cat </dev/tcp/time.nist.gov/13
To download an unencrypted URL do this:
$ exec 5<>/dev/tcp/www.example.com/80 $ echo -e "GET http://www.example.com/ HTTP/1.0\n" >&5 $ cat <&5