перезагрузить несколько машин удаленно

11

Мне нужно перезагрузить несколько машин удаленно. Обычно я просто выдаю

for host in <hostlist>;do ssh ${host} 'sudo shutdown -r now';done

Но я хочу дать пользователям время до перезагрузки. Однако они не будут отключать ssh, даже если я использую:

ssh -f 'sudo shutdown -r +5 &;disown'

Я получаю сообщение об ошибке:

bash: -c: строка 0: синтаксическая ошибка рядом с неожиданным ;' bash: -c: line 0:отключением sudo токена -r +5 &; disown '

Какие-либо предложения?

Гораций
источник
1
Я должен добавить, что я пытаюсь отправить команду выключения в фоновом режиме с "&". Если оболочка интерпретирует «&» как разделитель команд, то я озадачен тем, как отправить его в фоновый режим, чтобы сработала команда «disown».
Гораций
&Персонаж делает послать команду на левой стороне в фоновом режиме. Вот как это отличается от ;.
Касперд

Ответы:

31

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

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

Это должно работать:

ssh server 'sudo shutdown -r +5 & disown'
kasperd
источник
7
Вы выиграли сегодняшний приз за то, что научили меня чему-то, чего я не знал после 25 лет борьбы с UNIX. Также +1!
MadHatter
Что, если он намеревался бежать sudo shutdown -r +5 &в фоновом режиме, а затем бежать disown? Как бы Bash справиться с такой ситуацией? Я ожидаю, что это будет идеальный синтаксис для команды, даже имея &;. Если ;это разделитель команд, то у вас есть 2 команды на руках. Правильно?
Исмаэль Мигель
1
@IsmaelMiguel Я не понимаю твоего вопроса. Использование &запускает первую команду в фоновом режиме, а после запуска первой команды вторая команда будет выполняться на переднем плане.
Касперд
Я имел в виду, что sudo shutdown -r +5 &; disownэто не похоже на плохой синтаксис. Я имею в виду, что я хотел бы запустить первую часть в фоновом режиме, а затем 2-ю часть.
Исмаэль Мигель
@IsmaelMiguel Анализатор команд, вероятно, можно расширить, чтобы считать пустую строку допустимой командой, которая всегда выполняется успешно. В этом случае sudo shutdown -r +5 &; disownбудут рассматриваться как три действительные команды, разделенные &и ;. Это, однако, означает, что нужно быть осторожным, чтобы не использовать дополнительный разделитель, если будет использоваться статус существования предыдущей команды. Это означает , что один должен обратить внимание на tokenizing, а так как , например , &&и & &получает лексемы по- разному.
Касперд