gpt4 book ai didi

perl - 通过ssh执行perl替换[shell脚本中的perl one-liner]

转载 作者:行者123 更新时间:2023-12-02 14:11:24 25 4
gpt4 key购买 nike

我正在尝试远程执行此脚本:

perl -i -pe 's/nginx-cache\K(\d+)/ ++($n = $1) /e; s/MYSITE\K(\w+)/ ++($n = $1) /e;' $SITENAME

使用以下解决方案:
ssh -T root@$IPSRV <<EOI
perl -i -pe 's/nginx-cache\K(\d+)/ ++($n = $1) /e; s/MYSITE\K(\w+)/ ++($n = $1) /e;' /etc/nginx/sites-available/$SITENAME"
exit
EOI

我也尝试了不使用ssh的“-T”选项
ssh root@$IPSRV "
> perl -i -pe 's/nginx-cache\K(\d+)/ ++($n = $1) /e; s/MYSITE\K(\w+)/ ++($n = $1) /e;' /etc/nginx/sites-available/$SITENAME"

但不幸的是,它不起作用:
syntax error at -e line 1, near "( ="
syntax error at -e line 1, near "( ="
Execution of -e aborted due to compilation errors.

有人可以建议我一个远程运行此命令的解决方案吗?
提前致谢!

请注意, $SITENAME是本地计算机上的变量。

[编辑]

根据@ikegami的回答,我已经取得了一些进展。
我试过了
root@$IPSRV 'perl -i -pe'\''s/nginx-cache\K(\d+)/ ++($n = $1) /e; s/MYSITE\K(\w+)/ ++($n = $1) /e;'\'' /etc/nginx/sites-available/"$SITENAME"'
root@192.168.1.100's password:
Can't do in place edit: /etc/nginx/sites-available/ is not a regular file.

我认为这与缺少$ SITENAME变量的替换有关。

要记住的另一件事是在ssh root @ IPSRV之后使用单引号-应该将其替换为引号,因为脚本中还有其他变量,如果我使用单引号,则不会对其进行翻译。
例:
ssh root@$IPSRV "mkdir $TESTDIR
cp /tmp/file $TESTDIR"

这有效,但是如果我尝试使用单引号:
ssh root@$IPSRV 'mkdir $TESTDIR
cp /tmp/file $TESTDIR'

它不是。因此,如果运行perl替换的唯一方法是'perl -i -pe'\ s,那么我也必须考虑这一方面。

谢谢!

最佳答案

转义不当。
ssh root@$IPSRV "...++($n = $1)..."...++( = )...传递到远程主机。与此处文档版本相同。 (here-doc版本也有误引号。)

处理多个级别的转义非常复杂,因此让我们以编程方式进行转义。这也使我们可以传递变量中的值,因为它们需要转换为 shell 文字。

quote() {
prefix=''
for p in "$@" ; do
printf "$prefix"\'
printf %s "$p" | sed "s/'/'\\\\''/g"
printf \'
prefix=' '
done
}

ssh root@$IPSRV "$( quote perl -i -pe'...' "$SITENAME" )"

要么
quote() {
perl -MString::ShellQuote=shell_quote -e'print(shell_quote(@ARGV))' "$@"
}

ssh root@$IPSRV "$( quote perl -i -pe'...' "$SITENAME" )"

为了对其他人有所帮助,下面显示了如何使用远程计算机的 $SITENAME var:
quote() {
prefix=''
for p in "$@" ; do
printf "$prefix"\'
printf %s "$p" | sed "s/'/'\\\\''/g"
printf \'
prefix=' '
done
}

ssh root@$IPSRV "$( quote perl -i -pe'...' )"' "$SITENAME"'

要么
quote() {
perl -MString::ShellQuote=shell_quote -e'print(shell_quote(@ARGV))' "$@"
}

ssh root@$IPSRV "$( quote perl -i -pe'...' )"' "$SITENAME"'

要么
ssh localhost sh <<'EOI'       # Notice the quotes around the token.
perl -i -pe'...' "$SITENAME"
EOI

或者,由于它不需要任何局部变量,因此您可以轻松地手动进行操作。接受远程命令,将每个 '替换为 '\'',然后用引号将其包装起来。

远程命令:
perl -i -pe'...' "$SITENAME"

本地命令:
ssh root@$IPSRV 'perl -i -pe'\''...'\'' "$SITENAME"'

关于perl - 通过ssh执行perl替换[shell脚本中的perl one-liner],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42541405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com