2013-03-13 4 views
10

В цикле скрипта оболочки я подключаюсь к различным серверам и запускаю некоторые команды. Напримерshell script ssh status status status

#!/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 

Здесь я бегу «Эхо $ HOST» и «PWD» команды, и я получаю состояние выхода через «эхо $?».

Мой вопрос в том, что я хочу иметь возможность сохранять статус выхода из команд, которые я запускаю удаленно в какой-либо переменной, а затем (на основе того, была ли команда успешной или нет), напишите журнал в локальный файл.

Любая помощь и код оцениваются.

ответ

19

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 

Вы также можете написать это:

+0

Вы говорите, что мне нужно ssh отдельно для запуска каждой команды, чтобы я мог получить их статус выхода? Я пытаюсь запустить как минимум 5 команд в том же сеансе ssh в моем реальном коде. –

+0

Привет, @larsks. Можете ли вы объяснить, что означает 'ssh localhost exit 10'? Это означает выполнение ssh localhost с явным 10 как код состояния? Здесь выход - это опция ssh или команда linux 'exit'? –

+0

Помните, что основным синтаксисом команды ssh является 'ssh '. Поэтому в приведенном выше ответе 'exit 10' - это команда, переданная удаленной оболочке. – larsks

0

Интересный подход состоял бы в том, чтобы получить весь вывод каждого набора команд ssh в локальной переменной с использованием обратных ссылок или даже отдельно с специальным charachter (для простоты сказать «:») som ething как:

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

после этого вы можете использовать awk разделить MYVAR в ваши результаты и продолжить тестирование Баш.

0

Возможно подготовить файл журнала на другой стороне и трубы его на стандартный вывод, например:

ssh -n [email protected] 'x() { local ret; "[email protected]" >&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 

Конечно, вы можете сделать это лучше интерпретируемым или адаптировать его к вашему whishes как файл_журнал будет выглядеть. Обратите внимание, что необработанный нормальный stdout удаленных программ записывается в stderr (см. Перенаправление в x()).

Если вам нужен рецепт для сбора и подготовки вывода команды для файла журнала, вот копия такого улавливателя от https://gist.github.com/hilbix/c53d525f113df77e323d - но да, это немного больший шаблон, чтобы «Запустить что-то в текущем контексте оболочки , постобработка стандартного вывод + 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 "[email protected]" "$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 
} 

Смотрите вторую последнюю строку для примера (прокрутите вниз)

2

Вы можете присвоить статус выхода переменных так просто, как делает:

var_name= $? 

Сразу после команды, которую вы пытаетесь проверить. Не используйте echo $? или новое значение $? будет кодом выхода echo (обычно 0).

Смежные вопросы