2016-06-29 4 views
3

Я хочу послать небольшой скрипт на удаленной машине с помощью SSHbash + Linux + как игнорировать символ «!»

сценарий

#!/bin/bash 
sleep 1 
reboot 

но я получаю событие не найдено - «!», Потому что

ssh 183.34.4.9 "echo -e '#!/bin/bash\nsleep 1\reboot>'/tmp/file" 
-bash: !/bin/bash\nsleep: event not found 

как игнорировать "!" char, поэтому скрипт будет успешно отправлен ssh?

примечание я не могу использовать «\» перед «!» потому что я получаю

more /tmp/file 
#\!/bin/bash 
sleep 1 
+1

обратная косая черта. – 123

ответ

3

Использование set +H перед вашей командой, чтобы отключить ! style history substitution:

set +H 
ssh 183.34.4.9 "echo -e '#!/bin/bash\nsleep 1\reboot>'/tmp/file" 

# enable hostory expnsion again 
set -H 
+0

Можно ли сделать chmod + x на той же линии? – Eytan

+0

yes (Я не хочу запускать ssh дважды, потому что chmod + x) – Eytan

+0

Что я имею в виду, если я могу добавить chmod + x/tmp/file после «#!/Bin/bash \ nsleep 1 \ reboot> '/ tmp/file "как #!/bin/bash \ nsleep 1 \ reboot> '/ tmp/file; chmod + x/tmp/file – Eytan

0

Я думаю, что командная строка не очень хорошо отформатированный. Вы можете отправить это:

ssh 183.34.4.9 'echo -e "#!/bin/bash\nsleep 1\nreboot">/tmp/file' 

Когда я говорю «не очень хорошо отформатированный» Я имею в виду вы поставите «>» внутри «эхо», и вы забыли добавить «п» до «перезагрузки», и вы положили «\ reboot ", который будет интерпретироваться как" CR "(возврат каретки), за которым следует команда" eboot "(что, я думаю, не существует).

Но что же трюк здесь, чтобы инвертировать изменения в запятых (') с (") и наоборот.

+0

О вашем вопросе «chmod + x на одной строке» ... Как насчет googleing «bash более одной команды в одной строке»? ... В любом случае вы можете добавить «; chmod + x/tmp/file» в конце вашей командной строки: 'ssh 183.34.4.9 'echo -e" #!/bin/bash \ nsleep 1 \ nreboot ">/tmp/file; chmod + x/tmp/file'' – r3npi2

0

Bash работает в интерактивном режиме (что означает, что вы подаете команды на него со стандартного ввода и exec(2) Выполнение команды из сценария оболочки), так что вам не нужно включать строку #!/bin/bash в этом случае (даже больше, bash должен просто игнорировать ее, но не включенный удар, поскольку он является частью активного механизма истории)

Но почему? Первые два символа в исполняемом файле (любой файл, способный быть exec(2) ed из seco ndary storage, а не ваш случай) имеют особое значение (для ядра и для оболочки): они являются магическим номером, что определяет тип исполняемого файла, в котором загружается ядро ​​. Это позволяет ядру выбирать правильные исполняемые процедуры загрузки в зависимости от исполняемого бинарного формата (и то, что позволяет вам, например, выполнять BSD-программы в ядрах linux и наоборот)

Специальное значение для этих магических чисел составлено два символа # и ! (в этом порядке), которые заставляют ядро ​​считывать полную первую строку этого файла и загружать исполняемый файл, указанный в этой строке, вместо этого, позволяя выполнять сценарии оболочки для разных интерпретаторов непосредственно из командной строки , И это делается специально, так как символ # обычно в сценарии оболочки описывает символ комментария. Это происходит только тогда, когда оболочка, интерпретирующая команды , не является интерактивной оболочкой. Когда оболочка загружает скрипт с этими символами, он обычно считывает первую строку и проверяет, имеет ли она знак #! и загружает надлежащий интерпретатор, реплицируя функцию ядра, которая делает это. Несмотря на то, что он является комментарием для оболочки, он позволяет обрабатывать файлы исполняемых файлов, которые не хранятся на вторичном хранилище (единственные системные вызовы exec(2)), но исходящие из stdin (как это происходит с вашими).

Поскольку ваша оболочка работает в интерактивном режиме, и вы хотите выполнять ее команды без изменения оболочки, вам не нужна эта строка и она может полностью ее устранить без необходимости отключать символ помех.

Извините, но решение дал о выполнении оболочки с -H вариант, вероятно, не будет жизнеспособным, как оболочка выполняет команды это Войти оболочки в целевой машине, так что вы не можете предоставить конкретные параметры для него (параметры выбираются программой login (8) и обычно не включают в себя произвольные параметры, такие как -H).

Лучшее решение - полностью устранить линию #!/bin/bash, так как вы не собираетесь делать exec(2), что программа в цель. Если вы хотите выбрать оболочку из строки ввода (в случае, если у пользователя есть другая оболочка, установленная в качестве оболочки входа в систему), лучше вызвать требуемую оболочку в командной строке и передать ее (через stdin или заставить ее прочитать сценарий оболочки как файл) команды оболочки, которые вы хотите выполнить (но опять же, без линии #!).

ПРИМЕЧАНИЕ

Важно, чтобы убедиться, что вы будете выполнять все это, так что лучше, чтобы передать все содержимое сценария в целевом назначения, и когда-то уверены, вы прошли все это, чтобы выполнить его в целом , Затем ваша первая строка #! будет правильно обработана, так как исполняемый файл будет запущен с помощью exec(2), сделанного из ядра.

Пример:

DIRECTORY=/bla/bla 
FILE=/path/to/file 
OUTPUT=/path/to/output 

# this is the command we want to pass through the line 
cat <<EOF | ssh [email protected] "cat >>/tmp/shell.sh" 
cd $DIRECTORY 
foo $FILE >$OUTPUT 
exit 0 
EOF 
# we have copied the script file in a remote /tmp/shell.sh 
# and we are sure it has passed correctly, so it's ready 
# for local execution there. 
# now, execute it. 
# the remote shell won't be interactive, and you'll ensure that it is /bin/bash 
ssh [email protected] "/bin/bash /tmp/shell.sh" >remote_shell.out 

Более система усложняет является один, что позволяет подписать скрипт перед отправкой, и проверить подпись сценария перед его выполнением, так что вы защищены от возможных троянских атак. Но это объяснение не соответствует действительности.

Другой вариант - использовать команду batch(2) удаленно и передать все команды, которые вы хотите выполнить. вы получите сеансовую исполняющую среду, более подходящую для требуемой задачи (несмотря на то, что вы получите скрипт, полученный по электронной почте, целевому пользователю, выполняющему сценарий)