shell脚本ssh命令退出状态

时间:2013-03-13 16:27:26

标签: shell ssh

在shell脚本的循环中,我连接到各种服务器并运行一些命令。例如

#!/bin/bash
FILENAME=$1
cat $FILENAME | while read HOST
do
   0</dev/null ssh $HOST 'echo password| sudo -S 
   echo $HOST 
   echo $?      
   pwd
   echo $?'
done

这里我正在运行“echo $ HOST”和“pwd”命令,我通过“echo $?”获得退出状态。

我的问题是,我希望能够将我在远程运行的命令的退出状态存储在某个变量中,然后(根据命令是否成功),将日志写入本地文件。

感谢任何帮助和代码。

4 个答案:

答案 0 :(得分:26)

ssh将退出远程命令的退出代码。例如:

$ ssh localhost exit 10
$ echo $?
10

因此,在您的ssh命令退出后,您只需检查$?即可。您需要确保不屏蔽返回值。例如,您的ssh命令以:

结束
echo $?

这将始终返回0.你可能想要的是更像这样的东西:

while read HOST; do
  echo $HOST
  if ssh $HOST 'somecommand' < /dev/null; then
    echo SUCCESS
  else
    echo FAIL
done

您也可以这样写:

while read HOST; do
  echo $HOST
  if ssh $HOST 'somecommand' < /dev/null
  if [ $? -eq 0 ]; then
    echo SUCCESS
  else
    echo FAIL
done

答案 1 :(得分:2)

您可以将退出状态分配给变量,只需执行以下操作:

variable=$?

在您尝试检查的命令之后。不要echo $?之前或$?的新值将是echo的退出代码(通常为0)。

答案 2 :(得分:0)

一个有趣的方法是使用反引号检索局部变量中每个ssh命令集的整个输出,或者甚至使用特殊的charachter(为简单起见“:”)分隔:

export MYVAR=`ssh $HOST 'echo -n ${HOSTNAME}\:;pwd'`

在此之后,您可以使用awkMYVAR拆分为结果并继续进行bash测试。

答案 3 :(得分:0)

也许准备另一边的日志文件并将其传递给stdout,如下所示:

ssh -n user@example.com 'x() { local ret; "$@" >&2; ret=$?; echo "[`date +%Y%m%d-%H%M%S` $ret] $*"; return $ret; };
x true
x false
x sh -c "exit 77";'  > local-logfile 

基本上只是使用此x包装器为要调用的远程上的所有内容添加前缀。它也适用于条件,因为它不会改变命令的退出代码。

您可以轻松循环此命令。

此示例将日志写入:

[20141218-174611 0] true
[20141218-174611 1] false
[20141218-174611 77] sh -c exit 77

当然,您可以使其更易于解析或使其适应您的日志文件的样子。请注意,远程程序的未捕获的正常stdout将写入stderr(请参阅x()中的重定向)。

如果您需要一个配方来捕获并准备日志文件的命令输出,这里有一个来自https://gist.github.com/hilbix/c53d525f113df77e323d的捕获器的副本 - 但是,这是一个更大的样板来“运行当前的东西shell的上下文,后处理stdout + stderr而不会打扰返回代码“:

# Redirect lines of stdin/stdout to some other function
# outfn and errfn get following arguments
# "cmd args.." "one line full of output"
: catch outfn errfn cmd args..
catch()
{
local ret o1 o2 tmp
tmp=$(mktemp "catch_XXXXXXX.tmp")
mkfifo "$tmp.out"
mkfifo "$tmp.err"
pipestdinto "$1" "${*:3}" <"$tmp.out" &
o1=$!
pipestdinto "$2" "${*:3}" <"$tmp.err" &
o2=$!
"${@:3}" >"$tmp.out" 2>"$tmp.err"
ret=$?
rm -f "$tmp.out" "$tmp.err" "$tmp"
wait $o1
wait $o2
return $ret
}

: pipestdinto cmd args..
pipestdinto()
{
local x
while read -r x; do "$@" "$x" </dev/null; done
}

STAMP()
{
date +%Y%m%d-%H%M%S
}

# example output function
NOTE()
{
echo "NOTE `STAMP`: $*"
}

ERR()
{
echo "ERR `STAMP`: $*" >&2
}

catch_example()
{
# Example use
catch NOTE ERR find /proc -ls
}

查看示例的第二行(向下滚动)