Bash set -x and stream
Can you explain the output of the following test script to me:
# prepare test data
echo "any content" > myfile
# set bash to inform me about the commands used
set -x
cat < myfile
output:
+cat
any content
Namely, why doesn't the line starting with + show the "<myfile" bit?
How do I get bash to do this. I need to tell the user about my script actions, as in:
mysql -uroot < the_new_file_with_a_telling_name.sql
I can not either.
EDIT : Additional context: I am using variables. Source:
SQL_FILE=`ls -t $BACKUP_DIR/default_db* | head -n 1` # get latest db
mysql -uroot mydatabase < ${SQL_FILE}
-v
will not expand variables, but cat file.sql | mysql
create two lines:
+mysql
+cat file.sql
so that's the trick.
source to share
Instead, you can try set -v
or set -o verbose
, which allows the command echo command.
Example execution on my machine:
[me@home]$ cat x.sh
echo "any content" > myfile
set -v
cat < myfile
[me@home]$ bash x.sh
cat < myfile
any content
The danger here is that it set -v
just literally intercepts the command and doesn't do any shell expansion or iterpolation. As Jonathan pointed out in the comments, it can be a problem if the file name is defined in a variable (for example command < $somefile
), making it difficult to determine what it refers to $somefile
.
source to share
The difference is pretty simple:
-
in the first case, you are using a program
cat
and you are redirecting the contentmyfile
to standard inputcat
. This means what you are performingcat
and whatbash
shows you when you haveset -x
; -
in a possible second case you can use
cat myfile
as @Jonathan Leffler pointed out and you will see+cat myfile
this is what you are doing: a programcat
with a parametermyfile
.
From man bash
:
-x After expanding each simple command, for command, case command,
select command, or arithmetic for command, display the expanded
value of PS4, followed by the command and its expanded arguments or
associated word list.
As you can see, it just displays the extended command line and the argument list - the redirects are not part of the extended command cat
or part of its argument list.
As @Shawn Chin pointed out, you can use set -v
that starting with man bash
:
-v Print shell input lines as they are read.
source to share
Basically, the method bash
works with your team -x
. I checked the Solaris 5.10 checkbox and /bin/sh
there (which is close to the genuine Bourne shell) also skips I / O redirection.
Given the batch file ( x3.sh
):
echo "Hi" > Myfile
cat < Myfile
rm -f Myfile
Trace output on Solaris machine:
$ sh -x x3.sh
+ echo Hi
+ cat
Hi
+ rm -f Myfile
$ /bin/ksh -x x3.sh
+ echo Hi
+ 1> Myfile
+ cat
+ 0< Myfile
Hi
+ rm -f Myfile
$ bash -x x3.sh
+ echo Hi
+ cat
Hi
+ rm -f Myfile
$
Note that bash
and sh
(which are certainly different executables) produce the same output. The output ksh
includes I / O redirection information - count 1 for the Korn shell.
For this specific example, you can use:
cat myfile
to see the file name. This is generally tricky, but use ksh
instead bash
to get I / O redirection.
source to share