Вы видите то, что происходит, и достигните желаемого поведения с ln
опции. Используйте этот псевдоним для ln
:
alias ln='\ln -vsn'
ln
опции:
-v, --verbose
print name of each linked file
-s, --symbolic
make symbolic links instead of hard links
-n, --no-dereference
treat destination that is a symlink to a directory as if it were a normal file
ssh
читает остальную часть Вашего стандартного входа.
while read HOST ; do … ; done < servers.txt
read
чтения от stdin. <
перенаправления stdin из файла.
К сожалению, команда, Вы пытаетесь выполнить также чтения stdin, таким образом, она завершает пищевую остальную часть Вашего файла. Вы видите его ясно с:
$ while read HOST ; do echo start $HOST end; cat; done < servers.txt
start server1.mydomain.com end
server2.mydomain.com
server3.mydomain.com
Заметьте как cat
поел (и отозвался эхом), оставление двумя строками. (Читал сделанный это как ожидалось, каждая строка будет иметь "запуск" и "конец" вокруг хоста.)
Почему делает for
работа?
Ваш for
строка не перенаправляет к stdin. (На самом деле это читает все содержание servers.txt
файл в память перед первым повторением). Так ssh
продолжает читать его stdin из терминала (или возможно ничто, в зависимости от того, как Ваш сценарий называют).
По крайней мере, в ударе, Вы можете иметь read
используйте другой дескриптор файла.
while read -u10 HOST ; do ssh $HOST "uname -a" ; done 10< servers.txt
# ^^^^ ^^
должен работать. 10
просто произвольный номер документа, который я выбрал. 0, 1, и 2 определили значения, и обычно вводные файлы начнут с первого доступного числа (таким образом, 3 будет рядом с использоваться). 10 таким образом достаточно высоко, чтобы остаться вне пути, но достаточно низко находиться под пределом в некоторых оболочках. Плюс он - круглое число...
Как McNisse указывает в его ответе, клиент OpenSSH имеет -n
опция это будет препятствовать тому, чтобы он читал stdin. Это работает хорошо в особом случае ssh
, но конечно другие команды могут испытать недостаток в этом — другая работа решений, независимо от которой команда ест Ваш stdin.
Вы можете, по-видимому (как в, я попробовал его, это работает в моей версии Bash, по крайней мере...), делают второе перенаправление, которое выглядит примерно так:
while read HOST ; do ssh $HOST "uname -a" < /dev/null; done < servers.txt
Можно использовать это с любой командой, но это будет трудно, если Вы на самом деле захотите терминальный вход, идущий в команду.
Поскольку derobert описывает ssh
чтения Ваш stdin
.
Для изменения этого поведения, можно добавить-n никакой ssh, чтобы препятствовать тому, чтобы он читал stdin.
ssh -n $HOST "uname -a"
Вы, вероятно, на самом деле были бы более обеспеченным использованием pssh из параллельного-ssh проекта.
pssh -h $hostfile -t $timeout -i $commands
-i
интерактивные средства. pssh также идет с параллелью scp и параллелью rsync. То, что хорошо, - то, что это работает асинхронно и выполнит столько потоков, сколько Вы спрашиваете это к. Значение по умолчанию (не-i/interactive) должно произвести для разделения каталогов для stdout/stderr, который оно делает $outputdir/$hostname.
При находке этого вида задачи довольно часто необходимо попробовать Матрицу
Установите Матрицу, следующую инструкциям, большинство случаев, в которых Вы просто нуждаетесь sudo apt-get install fabric
Создайте названный файл fabfile.py
со следующим кодом:
from fabric.api import env, run
env.hosts = ['server1.mydomain.com',
'server1.mydomain.com',
'server1.mydomain.com']
def mytask():
run('uname -a')
Затем выполненный fab mytask
даст Вам результат, который Вы хотите.
Это - более легкое использование команды как это:
for f in `cat servers.txt`; do ssh $f uname -a; done
Мне обычно нравится это:
for f in `cat servers.txt`; do echo "### $f ###"; ssh $f uname -a; done
echo
должен видеть, какой сервер застревает или не может соединиться с ним.
Поскольку команда ssh принимает весь поток из стандартного ввода, подаваемого оператором while,
Вы можете использовать канал для переключения stdin ssh на другой источник:
echo "" | ssh ...
пример:
while read HOST ; do echo "" | ssh $HOST "uname -a" ; done < servers.txt
stdin ввод всех Команды ssh в цикле while должны быть переключены на другой источник.
10
произойти из? – Martin Vegter 04.01.2014, 10:02exec 3<&0; while read HOST; do ssh $HOST "uname -a" <&3; done <servers.txt; exec 3<&-
Это делает дескриптор файла 3 резервное копирование исходного stdin, затем использует его для stdin ssh, затем закрывает резервный FD при выполнении. Это работает над любой совместимой с POSIX оболочкой. @DougO' Neal – Richard Hansen 08.01.2014, 20:49-u
опция не поддерживается POSIX и таким образом не должна использоваться для#!/bin/sh
сценарии; использоватьread HOST <&10
вместо этого. Кроме того, POSIX только требует оболочек к дескрипторам файла поддержки 0 до 9, таким образом,10<servers.txt
не может использоваться, если сценарий должен строго соответствовать. – Richard Hansen 08.01.2014, 20:58