2012-03-22 134 views
4

你看到有人试图“记录我运行的命令和命令的输出”的次数?它经常发生,并且对于看到您运行的命令set -v很好,(set -x也很好,但它可能更难读),但是当您想捕获正在运行的命令时会发生什么......但不是所有命令正在运行?bash:捕获set的输出-v

交互式运行我没有看到一种方法来捕获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 

啊哈,所以从剧本就进入标准错误。内联怎么样?

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' 

但肯定有更好的方法。

回答

4

您可以通过set与选项-v运行bash的,而不是打开和关闭:

bash -v -c "echo a" 1>/dev/null # prints 'echo a' 
bash -v -c "echo a" 2>/dev/null # prints 'a' 

这种解决方案的黑暗的一面是,每个这样的线将需要创建新的bash进程,但是您不必记得关闭v选项,因为它仅在子进程中打开。

+0

现在*那*是少得多哈克。无论如何,我的解决方法产生了大量的bash进程,所以这是一个直接的改进。 – Sorpigal 2012-03-22 20:07:10

+0

鉴于没有人似乎有更好的主意,我接受这一个。 – Sorpigal 2012-03-23 16:58:47

1

怎么样

#!/bin/bash 
set -o xtrace 
Stuff..... 
+0

超出范围!我不是想解决原始问题,我想捕获'set -v'的输出。 – Sorpigal 2012-03-22 18:47:20

+1

也许你可以使用-o选项调用bash,它只会将它传递给被生成的shell。比如bash -o xtrace gen.sh,那么你可以捕获stderr中的输出。我认为set -v与set -o verbose相同,所以bash -o verbose gen.sh应该完成这项工作。 – pizza 2012-03-22 19:07:24