我正在尝试让这个脚本工作(它应该做的是在远程服务器的最后一个日志文件中搜索字符串):
ssh -i $ssh_key_file ubuntu@$1 -t "cd /path/to/logs; grep \"POST api/orders \" `ls -Art | grep info | tail -n 1` -A 2 | grep \"'store_id' => '$2'\" -B 1; bash --login"
这个脚本
`ls -Art | grep info | tail -n 1`
应该返回给我最后一个日志文件,如果我在远程服务器上单独运行该脚本,这就是它的一个例子:
$ ls -Art | grep info | tail -n 1
info-2019-04-10.log
此外,如果我通过对日志文件名进行硬编码来运行与上面完全相同的脚本,那么它就可以正常工作:
ssh -i $ssh_key_file ubuntu@$1 -t "cd /path/to/logs; grep \"POST api/orders \" info-2019-04-10.log -A 2 | grep \"'store_id' => '$2'\" -B 1; bash --login"
我能够将此(查找最后一个日志文件)脚本嵌入到其他 shell 脚本中,并且它运行良好,如下所示:
ssh -i $ssh_key_file ubuntu@$1 -t "cd /path/to/logs; grep $2 `ls -Art | grep info | tail -n 1`; bash --login"
我在原始脚本中做错了什么?
更新
使用此脚本
function totCreateOrder()
{
ssh -i "$ssh_key_file" ubuntu@"$1" -t<<EOF
cd /var/www/toters/storage/logs && grep "POST api/orders " "\$(ls -Art | grep info | tail -n 1)" -A 2 \
| grep "'store_id' => '"'$2'"'" -B 1
bash --login
EOF
}
返回这个奇怪的错误消息
totCreateOrder $prod1as 1006
Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1067-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
74 packages can be updated.
0 updates are security updates.
New release '18.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
*** System restart required ***
我抬头望去这个错误意味着什么,然后做了这个
function totCreateOrder()
{
ssh -i $ssh_key_file ubuntu@$1 -t -t<<EOF
cd /var/www/toters/storage/logs && grep "POST api/orders " "\$(ls -Art | grep info | tail -n 1)" -A 2 \
| grep "'store_id' => '"'$2'"'" -B 1
EOF
}
但后来我收到这个错误信息:
totCreateOrder $prod1as 1006
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1067-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
74 packages can be updated.
0 updates are security updates.
New release '18.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
*** System restart required ***
Last login: Thu Apr 11 03:38:32 2019 from 185.81.141.32
1"$(ls -Art | grep info | tail -n 1)" -A 2 | grep "'store_id' => '"'1006'"'" -B
更新二
我逐行检查了脚本...它确实起到了作用,因为它实现了以下效果:
- 登录到远程服务器
- 能够
ls -Art | grep info | tail -n 1
正确解析 在远程服务器上运行此命令:
grep "POST api/orders " "$(ls -Art | grep info | tail -n 1)" -A 2
函数测试(){ ssh -i $ssh_key_file ubuntu@$1 -t -t<
它返回了这个
test $prod1as
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1067-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
74 packages can be updated.
0 updates are security updates.
New release '18.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
*** System restart required ***
Last login: Thu Apr 11 05:18:10 2019 from 185.81.141.85
ubuntu@ip-x-xx-xx:~$ cd /var/www/toters/storage/logs
-Art | grep info | tail -n 1)" -A 2 storage/logs$ grep "POST api/orders " "$(ls
[2019-04-11 04:10:39] production.INFO: POST api/orders [] []
[2019-04-11 04:10:39] production.INFO: array ( 'store_id' => '831', 'items' => array ( 0 => array ( 'additional_info' => '', 'addons' => array ( ), 'quantity' => 1, 'id' => 129369,
), 1 => array ( 'additional_info' => '', 'addons' => array ( ), 'quantity' => 1, 'id' => 133351, ), 2 => array ( 'additional_info' => '', 'addons' => ..
然而当我像这样添加管道时,事情就发生了变化:
function test()
{
ssh -i $ssh_key_file ubuntu@$1 -t -t<<EOF
cd /var/www/toters/storage/logs
grep "POST api/orders " "\$(ls -Art | grep info | tail -n 1)" -A 2 | grep "'store_id' => '"'$2'"'" -B 1
EOF
}
它返回这个
$ test $prod1as 1006
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1067-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
74 packages can be updated.
0 updates are security updates.
New release '18.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
*** System restart required ***
Last login: Thu Apr 11 05:33:22 2019 from 185.81.141.85
ubuntu@ip-10-0-1-39:~$ cd /var/www/toters/storage/logs
-Art | grep info | tail -n 1)" -A 2 | grep "'store_id' => '"'1006'"'" -B 1"$(ls
答案1
我在原始脚本中做错了什么?
主要问题是:双引号中的反引号在本地扩展。通常我会推荐 here document,但对于你的情况,你需要一个伪终端,并且无法真正重定向标准输入(这是 here document 所做的)。无论如何,使用$()
而不是反引号并转义$
(或者你可以坚持使用反引号并转义它们,但$()
总体而言) 或用单引号括住此片段。这应将整个$( … )
语法传递到远程端。您还应确保远程 shell 将其放在双引号中,因为很明显,在这种情况下您不希望结果经过分词和模式匹配。
一般来说不应该解析ls
。我猜很难用更强大的代码替换您的代码,除非find
远程端支持-printf
。但我不知道它是否支持,所以我不会改进这部分。(除了这个:为什么要反转输出ls
并取最后一个条目?为什么不从非反转输出中取第一个条目?您grep
支持吗-m 1
?)
grep
如果失败则不应调用cd
。
您应该对变量使用双引号,除非您知道不需要这样做。:) 不引用$ssh_key_file
可能$1
会打开一个罐头……惊喜.$2
在您的代码中有些不同。从上下文来看,它应该在本地扩展,并将结果传递给远程 shell。无论到达远程 shell 的是什么,解析。我猜你不希望本地扩展的结果$2
在远程端进行变量扩展(或者你想?)。在你的原始脚本中,远程 shell 会看到$2
在双引号内的单引号中本地扩展的外在的东西很重要。因此,您应该让本地扩展的$2
字符串在单引号中出现在远程 shell 中。但是,如果您将此字符串嵌入为模式的一部分grep
,则应该将它们用双引号引起来。这会导致引用混乱,这很棘手。
你传递给远程 shell 的仍然是一个字符串,它将是解析,(本地)的某些值$2
将破坏代码。代码注入是可能的。这是一个常见问题,其中依赖于变量的命令作为要解析的字符串传递,这很难清理。我希望你能完全控制本地$2
。如果没有,这是一个漏洞:任何控制它的人都可以以远程主机上的用户身份运行任意命令。例如,如果在扩展为(双引号属于此处的变量)ubuntu
时运行原始代码,你会感到不愉快的惊讶(所以不要这样做)。$2
"& rm -rf ~/ & "
以下代码片段完全未经测试。您的代码看起来非常具体,因此很难测试。
ssh -i "$ssh_key_file" ubuntu@"$1" -t "
cd /path/to/logs && grep \"POST api/orders \" \"\$(ls -Art | grep info | tail -n 1)\" -A 2 \
| grep \"'store_id' => '\"'$2'\"'\" -B 1
bash --login
"
笔记:
- 由于本地扩展
$2
和单引号需要到达远程端,我决定将整个命令用双引号引起来。将部分命令放在单引号中可能会减少引用(和转义)的混乱,但这不一定会使命令变得不那么神秘,因为很难发现哪部分是以何种方式引用的。 $2
仍然可以进行代码注入。
录取后通知
OP 报告以下代码有效:
function test()
{
ssh -i "$ssh_key_file" ubuntu@"$1" -t "cd /path/to/logs; grep \"POST api/orders \" \"\$(ls -Art | grep info | tail -n 1)\" -A 2 \
| grep \"'store_id' => '\"'$2'\"'\" -B 1 \
; bash --login"
}
此代码以与上述代码相同的方式修复了主要问题。变化可能在语法方面很重要(?),但我认为它们对于主要问题来说是次要的。