我正在尝试ssh到服务器,并检查id_rsa.pub是否存在。如果它不存在,我想运行ssh-keygen,否则我不想做任何事情。
我可以使用Tcl / Expect中的send来运行像“cat”或“rm”这样的命令,但是当我尝试做这样的事情时它不起作用:
send "if [ ! -f $USER_SSH_PATH/id_rsa.pub ]; then CREATE_FILE=true; fi\r"
expect "# " { }
send "if $CREATE_FILE; then; ssh-keygen -t rsa -C $USER -f $USER_SSH_PATH/id_rsa\r"
...
我收到以下错误消息: #valid命令名“!” 执行时 “!-f /root/.ssh/id_rsa.pub” 从
中调用是否可以运行这样的命令?
答案 0 :(得分:4)
你需要转义方括号,因为它是tcl语法的一部分:
send "if \[ ! -f $USER_SSH_PATH/id_rsa.pub \]; then CREATE_FILE=true; fi\r"
在tcl中,[]
的工作方式与b ``
或$()
的工作方式相同。所以发生的事情是,在执行send
命令之前,解释器首先对字符串进行替换,并且它会看到需要替换的两件事:
$ USER_SSH_PATH将替换为变量USER_SSH_PATH中包含的值
[! ....]被调用!
函数/命令的结果替换。您发现的不存在。
请注意,在tcl(并且通过扩展期望)中,变量和函数名称不限于字母数字。拥有$
或!
等变量和函数名称,甚至是NUL字符(值为0的字节)都是有效的:
proc ! {} {puts "!"}
proc "$" {} {puts "\$"}
proc \0 {} {puts "NUL character"}
! ;# this prints !
\$ ;# this prints $
\0 ;# this prints "NUL character"
有关tcl语法的更多信息,请参阅http://www.tcl.tk/man/tcl/TclCmd/Tcl.htm。
答案 1 :(得分:1)
正如slebetman已经指出的那样,[
,]
,$
和\
中的字符在"
中具有特殊含义。
[
和]
用于命令替换,因此[expr {2+3}]
将替换为5
(结果)。$
用于变量替换。\
用于特殊字符(如代码点为13的字符的\r
)您可以使用"
转义\
内的这些字符:我假设$USER_SSH_PATH
是本地(tcl)变量
send "if \[ ! -f $USER_SSH_PATH/id_rsa.pub \]; then CREATE_FILE=true; fi\r"
或使用{
和}
围绕您的字符串
如果您使用{
和}
,则不会进行替换。这还包括\r
将\r
作为-nocommands
发送到服务器,而不是单个字符。
还有一些其他选项可以创建这样的东西:
subst
可以对字符串进行替换。也可能只发生某些类型的替换(使用[]
开关来阻止-novariables
替换,使用$
进行-nobackslashes
替换,\
进行send [subst -nocommands \
{if [ ! -f $USER_SSH_PATH/id_rsa.pub ]; then CREATE_FILE=true; fi\r}]
{1}})
例如:
send [string map [list {@@r@@} \r {@@USER_SSH_PATH@@} $USER_SSH_PATH] \
{if [ ! -f @@USER_SSH_PATH@@/id_rsa.pub ]; then CREATE_FILE=true; fi@@r@@}]
string map
替换某些序列
实施例
{{1}}
有很多方法可以做这些事情。
答案 2 :(得分:0)
$USER_SSH_PATH
中的内容是什么?在本地和远程计算机上是否相同,这意味着您拥有正确的权限......以下内容可帮助您进行调试。
echo ${USER_SSH_PATH}
ssh <hostname> "
if [ ! -f ${USER_SSH_PATH}/id_rsa.pub ]; then
echo ${USER_SSH_PATH};
echo \"File Not Found, Creating....\";
ssh-key-gen -t rsa -C ${USER} -f ${USER_SSH_PATH}/id_rsa;
else
echo \"File Found\";
exit 1;
fi
"
答案 3 :(得分:0)
我刚想到的一个解决方案是在发送中运行“ls /root/.ssh/ | grep id_rsa.pub”并使用expect查看输出。我很好奇我如何在命令中运行bash。
我要么得到“id_rsa.pub”作为回报,要么是空行。但如果我有“id_rsa.pub *”,它就会破裂。
有人有想法改善这个吗?谢谢!