你有多少次见过有人试图“记录我运行的命令和命令的输出”?它经常发生,并且看到你正在运行的命令set -v
很好,(set -x
也很好,但它可能更难阅读),但是当你想要捕获正在运行的命令但没有运行所有命令时会发生什么?
以交互方式运行我根本没有找到捕获set -v
输出的方法。
set -v
echo a 1>/dev/null # 'echo a 1>/dev/null' is printed to the screen
echo a 2>/dev/null # 'echo a 2>/dev/null\na' is printed to the screen
我可以把它放在一个脚本中,事情会变得更好:
echo 'set -v'$'\n''echo a' > setvtest.sh
bash setvtest.sh 1>/dev/null # 'echo a' is printed to the screen
bash setvtest.sh 2>/dev/null # 'a' is printed to the screen
<啊>啊哈,所以从脚本转到stderr。内联怎么样?
set +v
{ set -v ; echo a ; } 1>/dev/null # no output
set +v
( set -v ; echo a ; ) 1>/dev/null # no output
嗯,那里没有运气。
有趣的是,作为旁注,这不会产生任何结果:
echo 'set -v ; echo a' > setvtest.sh
bash setvtest.sh 1>/dev/null
我不知道为什么,但也许这就是为什么子shell版本什么都不返回。
shell函数怎么样?
setvtest2 () {
set -v
echo a
}
setvtest2 # 'a'
set +v
setvtest2 1>/dev/null # nothing
set +v
setvtest2 2>/dev/null # nothing
现在的问题是:有没有很好的方法来捕获set -v
的输出?
这是我不太好的黑客,所以我正在寻找一些不那么疯狂的东西:
#!/usr/bin/env bash
script=/tmp/$$.script
output=/tmp/$$.out
echo 'set -v'$'\n'"$1" >"$script"
bash "$script" 1>"$output"
cat "$output"
rm -f "$script" "$output"
现在我可以执行简单的脚本
bash gen.sh 'echo a' 1>/dev/null # prints 'echo a'
bash gen.sh 'echo a' 2>/dev/null # prints 'a'
但肯定有更好的方法。
答案 0 :(得分:4)
您可以使用选项-v
运行bash,而不是通过set
开启和关闭:
bash -v -c "echo a" 1>/dev/null # prints 'echo a'
bash -v -c "echo a" 2>/dev/null # prints 'a'
这个解决方案的阴暗面是,每个这样的行都需要创建新的bash过程,但你不必记得关闭v
选项,因为它只在子进程中打开
答案 1 :(得分:1)
怎么样
#!/bin/bash
set -o xtrace
Stuff.....