myfile # set ...">

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.

+3


source to share


3 answers


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

.

+4


source


The difference is pretty simple:

  • in the first case, you are using a program cat

    and you are redirecting the content myfile

    to standard input cat

    . This means what you are performing cat

    and what bash

    shows you when you have set -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 program cat

    with a parameter myfile

    .

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.

      

+2


source


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.

+2


source







All Articles