我在这里坚持这段代码
user@server:~$ TEST="ssh [email protected] 'date; hostname -A; uname -a'" user@server:~$ $TEST bash: date; hostname -A; uname -a: Command not found.
我想在一个shell脚本里面使用这个,不知道是什么问题。 这两个系统都是debian wheezy,
但是如果直接执行命令:
user@server:~$ ssh [email protected] 'date; hostname -A; uname -a' Fre Aug 23 20:02:55 CEST 2013 otherserver.example.org Linux otherserver 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 GNU/Linux
那么最重要的是什么? 我接力错过了一些非常微不足道的东西,但只是无法弄清楚…请帮助…
这个背后的想法是,我在一个脚本内部build立一个长string,并在一个SSH会话中远程执行它(重新命名zfs快照,所有在一行n.0成为n.1等等)
但它不工作是希望它工作…
编辑/更新:更新了我的问题(从'date;date;date到'date;主机名-A; uname -a')的beeter理解exaples
感谢所有迄今为止的回应。 起初eval作品,但似乎不赞成用户所述。 所以我的工作是再次弄清楚如何改变它。
这个string女巫如此构build看起来像这样:
echo "Rearanging snapshots..." last_backup=7 first_backup=0 RENAME_STRING="'sudo zfs destroy $BACKUP_DATASTORE@n.$last_backup; " while [ $last_backup -gt $first_backup ] do RENAME_STRING=$RENAME_STRING"sudo zfs rename $BACKUP_DATASTORE@n.$(($last_backup - 1)) $BACKUP_DATASTORE@n.$last_backup" if [ $(($last_backup - 1 )) -gt $first_backup ] then RENAME_STRING=$RENAME_STRING"; " else RENAME_STRING=$RENAME_STRING"'" fi last_backup=$(($last_backup - 1 )) done #CURRENTLY SOLVED WITH EVAL as this one doesn't work... #remote_cmd=(/usr/bin/ssh "$BACKUP_USER@$HOST_TO" "$RENAME_STRING") #"${remote_cmd[@]}" eval /usr/bin/ssh $BACKUP_USER@$HOST_TO $RENAME_STRING
所以,也许你们会有一个更优雅的方式来解决这个问题?
EDIT2:
这个输出是“OK”吗? (好,在不废弃的手段,好与工作?
user@server:~$ TEST="date ; hostname -A ; uname -a" user@server:~$ ssh [email protected] <<< "$(printf '%s ' $TEST)" Pseudo-terminal will not be allocated because stdin is not a terminal. Linux otherserver 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Fre Aug 23 20:13:53 CEST 2013 otherserver.example.org Linux otherserver 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 GNU/Linux
EDI3:更新/改进(?)虽然仍然使用循环评估<<<不会在脚本中工作…
build议通过ssh远程执行本地命令的方法不是使用eval。 这是不鼓励的。 既然你将整行存储在一个variables中,你可以
mydate=$(date; date; date); ssh [email protected] bash <<< "$(printf 'echo %q ' "$mydate")"
Eval只能用于那些不提供安全工具的遗留系统,例如我向您展示的示例。
这将产生与使用交互式shell运行这些命令完全相同的结果。
希望至less给你一些想法。
更新来演示如何命令可以远程运行,而无需定义本地变种。
ssh [email protected] bash <<< "$(printf '%s ' "whoami && ps aux")"
尝试shell / bash build-in eval命令:
$ help eval eval: eval [arg ...] Execute arguments as a shell command. Combine ARGs into a single string, use the result as input to the shell, and execute the resulting commands. Exit Status: Returns exit status of command or success if command is null.
没有理由编写如此长的一串命令来通过SSH运行。 只需在名为/usr/local/sbin/rotate_backups的远程主机上build立一个永久性脚本,并用ssh $USER@$HOST 'sudo /usr/local/sbin/rotate_backups'调用它。
如果您在“Unix&Linux” StackExchange上提出这个问题,那么这可能是一个有趣的问题。 但是,作为系统pipe理员,您的目标应该是可维护性和安全性。 如果你无法理解你的剧本,你的同事和继任者将会诅咒你。
尝试这个:
user@server:~$ remote_cmd=(ssh [email protected] 'date; hostname -A; uname -a') user@server:~$ "${remote_cmd[@]}"
它创build一个数组并按照BashFAQ / 050第 3项的build议执行它。
问题find了
我开始了我的长长的一串'并与一个单一的'
现在我保留所有thos单引号( ' )自己创buildstring,并在最后添加一个双引号,所有作品!
#!/bin/sh ... #[SOME_CODE_HERE] ... echo "Rearanging snapshots..." last_backup=7 first_backup=0 RENAME_STRING="sudo zfs destroy $BACKUP_DATASTORE@n.$last_backup; " while [ $last_backup -gt $first_backup ] do RENAME_STRING=$RENAME_STRING"sudo zfs rename $BACKUP_DATASTORE@n.$(($last_backup - 1)) $BACKUP_DATASTORE@n.$last_backup; " last_backup=$(($last_backup - 1 )) done /usr/bin/ssh $BACKUP_USER@$HOST_TO "$RENAME_STRING"
所以有人可以向我解释这一点,为什么我不能在我的variables里面设置引号?
现在这个构造工作得很好。 感谢大家的帮助! 我希望我的回答也能帮助别人! (ALL_CAPITAL的东西将在稍后解决;))