bash set -x 和流

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14461871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 04:20:02  来源:igfitidea点击:

bash set -x and stream

bash

提问by bartekbrak

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 does the line starting with + not show the "< myfile" bit?

即为什么以 + 开头的行不显示“< myfile”位?

How to force bash to do that. I need to inform the user of my script's doings as in:

如何强制 bash 这样做。我需要将我的脚本的行为告知用户,如下所示:

mysql -uroot < the_new_file_with_a_telling_name.sql

and I can't.

我不能。

EDIT: additional context: I use variables. Original code:

编辑:附加上下文:我使用变量。原始代码:

SQL_FILE=`ls -t $BACKUP_DIR/default_db* | head -n 1` # get latest db
mysql -uroot mydatabase < ${SQL_FILE}

-vwon't expand variables and cat file.sql | mysqlwill produce two lines:

-v不会扩展变量cat file.sql | mysql并将产生两行:

+mysql
+cat file.sql

so neither does the trick.

所以诀窍也没有。

回答by Shawn Chin

You could try set -vor set -o verboseinstead which enables command echoing.

您可以尝试set -vset -o verbose改为启用命令回显。

Example run 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 caveat here is that set -vsimply echos the command literally and does not do any shell expansion or iterpolation. As pointed out by Jonathan in the comments, this can be a problem if the filename is defined in a variable (e.g. command < $somefile) making it difficult to identify what $somefilerefers to.

这里需要注意的是,它set -v只是简单地从字面上回显命令,并且不进行任何 shell 扩展或迭代。正如乔纳森在评论中指出的那样,如果文件名是在变量中定义的(例如command < $somefile),这可能是一个问题,从而难以识别$somefile所指的内容。

回答by Rubens

The difference there is quite simple:

区别很简单:

  • in the first case, you're using the program cat, and you're redirecting the contents of myfileto the standard input of cat. This means you're executing cat, and that's what bashshows you when you have set -x;

  • in a possible second case, you could use cat myfile, as pointed by @Jonathan Leffler, and you'd see +cat myfile, which is what you're executing: the program catwith the parameter myfile.

  • 在第一种情况下,您正在使用程序cat,并将 的内容重定向myfile到 的标准输入cat。这意味着您正在执行cat,这就是您执行bash时显示的内容set -x

  • 在可能的第二种情况下,您可以使用cat myfile,正如@Jonathan Leffler 所指出的那样,您会看到+cat myfile,这就是您正在执行的内容:cat带有参数的程序myfile

From man bash:

来自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 simply displays the command line expanded, and its argument list -- redirections are neither part of the expanded command catnor part of its argument list.

如您所见,它只是显示展开的命令行及其参数列表——重定向既不是展开命令的cat一部分,也不是其参数列表的一部分。

As pointed by @Shawn Chin, you may use set -v, which, as from man bash:

正如@Shawn Chin 所指出的,您可以使用set -v, 来自man bash

  -v      Print shell input lines as they are read.

回答by Jonathan Leffler

Basically, that's the way bashworks with its -xcommand. I checked on a Solaris 5.10 box, and the /bin/shthere (which is close to a genuine Bourne shell) also omits I/O redirection.

基本上,这就是bash-x命令的工作方式。我检查了 Solaris 5.10 框,/bin/sh那里(接近真正的 Bourne shell)也省略了 I/O 重定向。

Given the command file (x3.sh):

给定命令文件 ( x3.sh):

echo "Hi" > Myfile
cat < Myfile
rm -f Myfile

The trace output on the Solaris machine was:

Solaris 机器上的跟踪输出为:

$ 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 bashand sh(which are definitely different executables) produce the same output. The kshoutput includes the I/O redirection information — score 1 for the Korn shell.

请注意,bashsh(绝对是不同的可执行文件)产生相同的输出。该ksh输出包括I / O重定向信息-用于Korn外壳得分1。

In this specific example, you can use:

在此特定示例中,您可以使用:

cat myfile

to see the name of the file. In the general case, it is hard, but consider using kshinstead of bashto get the I/O redirection reported.

查看文件名。在一般情况下,这很难,但可以考虑使用ksh而不是bash获取报告的 I/O 重定向。