SSH 与 su 和远程命令使用 -c 并运行多个带有参数的命令

SSH 与 su 和远程命令使用 -c 并运行多个带有参数的命令

这是我的命令,其中 IP 已用语义 IP 注释掉

ssh -p 2022 -L 9389:localRDPIP:3389 user@publicIP \
su -c "export HISTCONTROL=ignorespace; \
iptables -t nat -A PREROUTING -p tcp --dport 3389 -j DNAT --to-destination localRDP_IP:3389; \
iptables -t nat -A POSTROUTING -p tcp -d localRDP_IP --dport 3389 -j SNAT --to-source jumpIP";

基本上,我正在尝试运行一些远程路由,这不是问题。问题是如何运行这样的命令?

我能做的最好的测试是:

ssh -p 2022 -L 9389:localRDPIP:3389 user@publicIP -t "su -c nano; nano"

但我不知道如何做空格。如果我的命令中的“引用区域”中有空格-c而不是单个命令,则会收到错误。

笔记:我意识到使用 ssh 端口转发,可能不需要 iptables 命令。

答案1

psql(以及扩展的 mysql)也有类似的限制。在阅读有关 psql 的文档时,我遇到了这个

-c command --command=command 指定psql是执行一个命令串,command,然后退出。这在 shell 脚本中很有用。使用此选项将忽略启动文件(psqlrc 和 ~/.psqlrc)。

命令必须是服务器完全可解析的命令字符串(即,它不包含特定于 psql 的功能),或者是单个反斜杠命令。因此,您不能将 SQL 和 psql 元命令与此选项混合使用。为此,您可以将字符串通过管道传输到 psql 中,例如: echo '\x \ SELECT * FROM foo;' | psql。 (\ 是分隔符元命令。)

如果命令字符串包含多个 SQL 命令,则它们将在单个事务中处理,除非字符串中包含显式的 BEGIN/COMMIT 命令以将其划分为多个事务。这与将相同字符串输入 psql 的标准输入时的行为不同。此外,仅返回最后一个 SQL 命令的结果。

由于这些遗留行为,在 -c 字符串中放入多个命令通常会产生意外结果。最好将多个命令提供给 psql 的标准输入,可以使用如上所示的 echo,也可以通过 shell here-document,例如:

psql <<EOF
\x
SELECT * FROM foo;
EOF

对于我的情况,我只是修改了我的 echo 语句

echo drop database if exists somedb; create database somedb;drop table if exists ur_table; CREATE TABLE ur_table (timestamp date, open real, high real,low real,close real,adjusted_close real,volume real,dividend_amount real,split_coefficient real,CONSTRAINT timestamp_pkey PRIMARY KEY (timestamp)); COPY ur_table(timestamp,open,high,low,close,adjusted_close,volume,dividend_amount,split_coefficient) FROM 'c:\test\temp.csv' DELIMITER ',' CSV HEADER;| psql -U postgres

答案2

su如( man su)的手册页所示,该-c选项采用单个 shell 命令,传递到当前 shell 以由其-c命令执行:

-c,--command COMMAND指定将由 shell 使用其-c.

COMMAND必须是单个参数,但是在更现代的版本中没有什么可以su阻止您引用多个命令以由调用以下命令的 shell 执行su

ssh -p 2022 -L 9389:localRDPIP:3389 user@publicIP su -c '
    export HISTCONTROL=ignorespace;
    iptables -t nat -A PREROUTING -p tcp --dport 3389 -j DNAT --to-destination localRDP_IP:3389;
    iptables -t nat -A POSTROUTING -p tcp -d localRDP_IP --dport 3389 -j SNAT --to-source jumpIP
'

不过,我不完全确定您想通过第二个命令实现什么目标。目前,它被设置nano为以 root 用户身份运行,然后以您自己的帐户再次运行。这是你想要的吗?或者您想nano以 root 用户身份运行两次,如下所示:

ssh -p 2022 -L 9389:localRDPIP:3389 user@publicIP -t su -c 'nano; nano'

相关内容