Professional Documents
Culture Documents
---------------------------------------------
In the shell, what does “ 2>&1 ” mean?
For testing this, we need a simple command which will send something on
both outputs:
(Expecting you don't have a directory named /tnt, of course ;). Well,
we have it!!
The last command line dumps STDERR to the console, and it seem not to
be the expected behaviour... But...
If you want to make some post filtering about standard output, error
output or both:
Notice that the last command line in this paragraph is exactly same as
in previous paragraph, where I wrote seem not to be the expected behaviour (so,
this could even be an expected behaviour).
$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2 2>&1 | sed
's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan 7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory
Nota: &9 descriptor would occur spontaneously because of ) 9>&2.
Addendum: nota! With the new version of bash (>4.0) there is a new
feature and more sexy syntax for doing this kind of things:
$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory
$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1|
cat -n
1 O: drwxrwxrwt 118 root root 196608 Jan 7 12:29 /tmp
2 E: ls: cannot access /tnt: No such file or directory
$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
1 O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
2 E: ls: cannot access /tnt: No such file or directory
$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)
$ set -o noclobber
$ set +o noclobber
$ rm $testfile
For redirecting both output from a given command, we see that a right
syntax could be:
(https://i.stack.imgur.com/huKF2.png)
(http://www.catonmat.net/blog/bash-one-liners-explained-part-three/)
-----------------------------------------------------------------------------------
---------------------------------------------
-----------------------------------------------------------------------------------
---------------------------------------------
Write output of bash script to file with date
-----------------------------------------------------------------------------------
---------------------------------------------
In a Bash script, how can I exit the entire script if a certain condition occurs?
exit 1
Code Meaning
Example
Comments
1 Catchall for general errors let "var1 =
1/0" Miscellaneous errors, such as "divide by zero" and other
impermissible operations
2 Misuse of shell builtins
empty_function() {} Missing keyword or command, or permission
problem
126 Command invoked cannot execute /dev/null
Permission problem or command is not an executable
127 "command not found"
illegal_command Possible problem with $PATH or a typo
128 Invalid argument to exit exit 3.14159
exit takes only integer args in the range 0 - 255
128+n Fatal error signal "n" kill -9 $PPID of
script $? returns 137 (128 + 9)
130 Script terminated by Control-C Ctl-C Control-C
is fatal error signal 2, (130 = 128 + 2, see above)
255* Exit status out of range exit -1
exit takes only integer args in the range 0 - 255
-----------------------------------------------------------------------------------
---------------------------------------------
-----------------------------------------------------------------------------------
---------------------------------------------
How to call one shell script from another shell script?
I have two shell scripts, a.sh and b.sh.
How can I call b.sh from within the shell script a.sh?
1. Make the other script executable, add the #!/bin/bash line at the
top, and the path where the file is to the $PATH environment variable. Then you can
call it as a normal command;
The first and third methods execute the script as another process, so
variables and functions in the other script will not be accessible.
The second method executes the script in the first script's process, and
pulls in variables and functions from the other script so they are usable from the
calling script.
In the second method, if you are using exit in second script, it will exit
the first script as well. Which will not happen in first and third methods.
OR
#!/bin/bash
echo "This script is about to run another script."
sh ./script.sh
#This assumes that script.sh is in the same directory as the whatever
script is running. If you wanted to call a script somewhere else, you would say sh
<path to script>/script.sh
echo "This script has just run another script."
OR
There are a couple of ways you can do this. Terminal to execute the script:
#!/bin/bash
SCRIPT_PATH="/path/to/script.sh"
# or
source "$SCRIPT_PATH"
# or
bash "$SCRIPT_PATH"
# or
eval '"$SCRIPT_PATH"'
# or
OUTPUT=$("$SCRIPT_PATH")
echo $OUTPUT
# or
OUTPUT=`"$SCRIPT_PATH"`
echo $OUTPUT
# or
("$SCRIPT_PATH")
# or
(exec "$SCRIPT_PATH")
All this is correct for the path with spaces!!!
-----------------------------------------------------------------------------------
---------------------------------------------
-----------------------------------------------------------------------------------
---------------------------------------------
How can I check if a directory exists in a Bash shell script?
if [ -d "$LINK_OR_DIR" ]; then
if [ -L "$LINK_OR_DIR" ]; then
# It is a symlink!
# Symbolic link specific commands go here.
rm "$LINK_OR_DIR"
else
# It's a directory!
# Directory command goes here.
rmdir "$LINK_OR_DIR"
fi
fi
-----------------------------------------------------------------------------------
---------------------------------------------
Each field in a /etc/passwd line is separated by a colon, and the username is the
first field, so you need to filter each line to only show the characters up to the
first colon
If you're able to use other tools besides grep, here are other generally better
ways of doing it:
-----------------------------------------------------------------------------------
---------------------------------------------
-----------------------------------------------------------------------------------
---------------------------------------------
To write the output of a command to a file, there are basically 10 commonly used
ways.
Overview:
Please note that the n.e. in the syntax column means "not existing".
There is a way, but it's too complicated to fit into the column. You can find
a helpful link in the List section about it.
----------++---------------------++---------------------++------------
|| visible in terminal || visible in file || existing
----------++---------------------++---------------------++------------
Syntax || StdOut | StdErr || StdOut | StdErr || file
----------++----------+----------++----------+----------++------------
> || no | yes || yes | no || overwrite
>> || no | yes || yes | no || append
----------++----------+----------++----------+----------++------------
2> || yes | no || no | yes || overwrite
2>> || yes | no || no | yes || append
----------++----------+----------++----------+----------++------------
&> || no | no || yes | yes || overwrite
&>> || no | no || yes | yes || append
----------++----------+----------++----------+----------++------------
| tee || yes | yes || yes | no || overwrite
| tee -a || yes | yes || yes | no || append
----------++----------+----------++----------+----------++------------
n.e. (*) || yes | yes || no | yes || overwrite
n.e. (*) || yes | yes || no | yes || append
----------++----------+----------++----------+----------++------------
|& tee || yes | yes || yes | yes || overwrite
|& tee -a || yes | yes || yes | yes || append
----------++----------+----------++----------+----------++------------
List:
1. command > output.txt
The standard output stream will be redirected to the file only, it will
not be visible in the terminal. If the file already exists, it gets overwritten.
The standard output stream will be redirected to the file only, it will
not be visible in the terminal. If the file already exists, the new data will get
appended to the end of the file.
The standard error stream will be redirected to the file only, it will
not be visible in the terminal. If the file already exists, it gets overwritten.
The standard error stream will be redirected to the file only, it will
not be visible in the terminal. If the file already exists, the new data will get
appended to the end of the file.
Both the standard output and standard error stream will be redirected
to the file only, nothing will be visible in the terminal. If the file already
exists, it gets overwritten.
Both the standard output and standard error stream will be redirected
to the file only, nothing will be visible in the terminal. If the file already
exists, the new data will get appended to the end of the file..
The standard output stream will be copied to the file, it will still be
visible in the terminal. If the file already exists, it gets overwritten.
The standard output stream will be copied to the file, it will still be
visible in the terminal. If the file already exists, the new data will get appended
to the end of the file.
9. (*)
Bash has no shorthand syntax that allows piping only StdErr to a second
command, which would be needed here in combination with tee again to complete the
table. If you really need something like that, please look at "How to pipe stderr,
and not stdout?" on Stack Overflow for some ways how this can be done e.g. by
swapping streams or using process substitution.
Both the standard output and standard error streams will be copied to
the file while still being visible in the terminal. If the file already exists, it
gets overwritten.
Both the standard output and standard error streams will be copied to
the file while still being visible in the terminal. If the file already exists, the
new data will get appended to the end of the file.
-----------------------------------------------------------------------------------
---------------------------------------------