注意:我真的在这里寻找一个SSH-y解决scheme,不仅仅是bash-y 。
我需要通过编程执行一系列通过ssh的命令。 有很多方法可以做到这一点,但我找不到任何与我的限制:
一些命令在shell中设置variables。 所以我不认为我可以使这个工作使用多个shell。
其中一些variables是函数,而不是正常值,所以我不认为我可以简单地序列化env的输出来“还原”旧的环境。
我需要分别访问每个命令的stdout,stderr和退出代码。 这使得使用&&或者链接命令变得困难; 。 我相信这也使得难以使用screen ,因为我们无法可靠地告诉一个命令完成。
我需要实时访问stdout,stderr等,以便我们可以logging输出的时间。 (我用“实时”来表示“nowish”,而不是“hard real-time”或类似的东西)。
为什么我需要一个bash会话? 因为命令可能会在环境中存储任意的variables和函数。 例如,通常运行rvm ,这是一个先前运行的命令添加的bash函数。
为什么我不能使用&&或; ? 因为我需要单独的stdout和stderr或每个命令,这将混合他们。
为什么我不能使用屏幕? 因为我们想自动运行命令,而不是交互式会话的一部分。 考虑到这个困难:我不得不通过input表单redirect运行命令,通过redirect输出,然后scp返回结果。 我需要echo $? 得到退出代码。 我将无法为stderr / stdout添加时间戳。 我将无法超时该命令。 这将是令人难以置信的越野车。
如果你需要一些东西来捕获输出,与shell会话进行交互和/或与像screen这样的pty应用程序进行交互,你可以尝试在高级语言的SSH库(如Ruby's Net:SSH)中编写代码。 它有一点点的学习曲线,但是我相信会完成你所需要的一切。
我需要分别访问每个命令的stdout,stderr和退出代码。 这使得使用&&或;来链接命令变得困难。
那么,我不知道我是否真的推荐这个,但是你可以写一个像这样的shell函数:
function prefix () ( PREFIX="$1" OUT='' while read -r ; do OUT="${OUT}${PREFIX}${REPLY}"$'\n' done echo "$OUT" ) function run_cmd () { echo "Running command << $@ >> . . ." ( ( ( "$@" ; echo "\$?: $?" >&3 ) | prefix 'STDOUT: ' >&3 ) 2>&1 \ | prefix 'STDERR: ' ) 3>&1 }
然后,如果./foo.sh bar将foo\nbar\n打印到标准输出,并将baz\nbip\n到标准错误,并以代码1退出,则run_cmd ./foo.sh bar将打印如下所示的内容:
Running command << ./foo.sh bar >> . . . $?: 0 STDOUT: foo STDOUT: bar STDERR: baz STDERR: bip
这应该让你链接一系列的命令,只要你使用run_cmd为你需要的所有STDOUT / STDERR /退出代码。 (但是由于命令本身是以五层深度运行的,因此不能使用run_cmd来运行任何需要设置环境variables的命令供其他命令使用,希望你没有任何命令输出和设置variables?)
你已经看过pssh吗? 它涵盖了大部分的需求,并且具有一定的创造力和想象力,可以帮助您:
等等…
我也相信凯尔的做法是最有希望的。 如果不行的话,你可以用一种无限循环的方式编写你的主脚本,在这个循环中它会查找命令文件,然后使用stdout,stderr和退出代码以可用于你的目的的forms。
然后你会通过一个备用通道插入命令文件,可能只是scp或类似的东西。