файл - Захват SSH-вывода как переменной в скрипте bash




sed (2)

Я столкнулся с этой проблемой при написании сценария bash. В принципе, я хочу измерить время программы на удаленном сервере, поэтому я использую команду: /usr/bin/time -f %e sh -c "my command > /dev/null 2>&1" чтобы выполнить программа. Тем не менее, похоже, что я не могу полностью захватить вывод моей команды (SSH). Фактически, результат (время) продолжает печататься в stdout.

Полный код:

respond=$(ssh ${fromNode} /usr/bin/time "-f" "%e" "'sh' '-c' 'virsh migrate --live ${VM} qemu+ssh://${toNode}/system --verbose > /dev/null 2>&1'")

Значение ответа просто пуст, хотя время распечатывается до стандартного вывода.


Команда «time» выводит результат на stderr, а не на stdout. Таким образом, он не попадает в вашу переменную.

Вы должны перенаправить stderr в stdout, чтобы достичь того, чего вы хотите:

 result=$(ssh host time "command" 2>&1)

И ваш полный код может выглядеть примерно так:

 respond=$(ssh ${fromNode} /usr/bin/time "-f" "%e" "'sh' '-c' 'virsh migrate --live ${VM} qemu+ssh://${toNode}/system > /dev/null 2>&1'" 2>&1)

Попробуйте поменять порядок перенаправления (до 2>&1 >/dev/null ). Ваш текущий код отправляет как stdout, так и stderr в / dev / null (так что мне любопытно, почему что-то печатается вообще).

Почему это необходимо? Синтаксис 2>&1 означает 'дубликат stdout (дескриптор 1) как stderr (дескриптор 2)'; по сути, stderr превращается в копию текущего stdout. Если сначала поместить >/dev/null , то stdout сначала перенаправляется на / dev / null, а затем stderr указывается на текущий stdout, то есть / dev / null.

Но если вы поместите >/dev/null second, stderr сначала станет копией текущего stdout (нормального выходного потока), прежде чем перенаправление stdout будет перенаправлено. Поэтому stderr команды печатает в tty (или интерпретаторе), как если бы он поступал из stdout, в то время как stdout отключен. Это поведение, которое вы хотите.

От man bash :

Обратите внимание, что порядок перенаправления значителен. Например, команда

ls > dirlist 2>&1

направляет как стандартный вывод, так и стандартную ошибку в файл dirlist, а команда

ls 2>&1 > dirlist

направляет только стандартный вывод в файл dirlist, поскольку стандартная ошибка дублируется как стандартный вывод до того, как стандартный вывод был перенаправлен на dirlist.







stdout