有没有办法为单个命令设置 bash 标志?

有没有办法为单个命令设置 bash 标志?

有更好的方法来做到这一点吗?

set -x; ls; set +x
# rest of the script

答案1

对于您展示的情况,您可以使用

( set -x; ls )

set操作会修改子 shell 中的本地环境,但不会修改子 shell 外部的环境。

请注意,子 shell 无法更改父环境中的任何内容,例如变量的值等。

另请注意,您的代码xtrace在最后无条件地取消设置 shell 选项(即,即使使用 调用脚本,它也会将其关闭bash -x),而使用子 shell(如上所示)将保留原始设置,无论是否set -x处于活动状态或者从一开始就没有。

有关的:

答案2

从版本 4.4 开始,第一组选项中的选项(使用set//设置的选项与使用without设置的选项相反)可以使用à la ash (是记录当前启用选项集的特殊参数)set -o作为函数的本地选项),因此您可以定义一个函数,例如:shopt -oshopt-olocal -$-

xtrace() {
  local -
  set -o xtrace
  "$@"
}

并致电:

xtrace ls

xtrace请注意,由于该命令是在该函数的上下文中调用的,xtrace return所以 orxtrace typeset varxtrace shift不会按预期工作。

您还可以借此机会PS4在函数中进行本地定义:

xtrace() {
  local - PS4='xtrace: running '
  set -o xtrace
  "$@"
}
bash-5.2$ xtrace echo "hello world"
xtrace: running echo 'hello world'
hello world

的等效语法zsh是:

xtrace() {
  set -o localoptions -o xtrace
  local PS4='...'
  "$@"
}

答案3

主要取决于您所说的“更好的“。例如,您可以使用子shell,

( set -x; ls )

答案4

您还可以使用命令而不是( ... )添加-x标志来调用新的 shell。

bash -x -c 'ls'

如果您想使用与当前环境不同的 shell,这可能很有用。

相关内容