V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
bluehtt
V2EX  ›  Linux

请大家帮忙看看 ssh 远程命令如何避免被本地解析?

  •  1
     
  •   bluehtt · 2020-10-30 18:00:39 +08:00 · 2560 次点击
    这是一个创建于 1477 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概意思是本地服务器 A 发送命令到指定服务器 B,使服务器 B 启动 nginx 容器,并且将服务器 B 的 /etc/hosts 记录添加到 nginx 容器中。远程执行命令如下:

    $ ssh root@host "docker run -d --name nginx-test $(cat /etc/hosts | grep '^192'| awk '{print "--add-host " $2":"$1}' | awk '{if(NR%900==0){printf $0 "\n"}else{printf "%s ",$0}}')  -p 80:80 nginx"
    

    执行命令后没有按照预想的将服务器 B 的 hosts 记录添加到 nginx 容器中,而是把服务器 A 的 hosts 记录添加了进去。这种情况有无办法处理?谢谢。

    第 1 条附言  ·  2020-10-30 19:16:33 +08:00

    最终通过 heredoc 的特性解决了问题,谢谢几位大佬,受益匪浅。

    $ ssh root@host $(
    cat << EOF
    docker run -d --name nginx-test $(cat /etc/hosts | grep '^192'| awk '{print "--add-host " $2":"$1}' | awk '{if(NR%900==0){printf $0 "\\n"}else{printf "%s ",$0}}') -p 80:80 nginx
    EOF
    )
    
    18 条回复    2022-03-03 09:23:02 +08:00
    wlsnx
        1
    wlsnx  
       2020-10-30 18:08:12 +08:00   ❤️ 1
    最外面的双引号换成单引号试试,如果不行就把命令写到脚本里上传到目标机器再执行
    rizon
        2
    rizon  
       2020-10-30 18:10:53 +08:00
    双引号的 $()会被执行的的。你换单引号 或者转义一下试试 "\$()"
    Jirajine
        3
    Jirajine  
       2020-10-30 18:14:03 +08:00 via Android
    把 $ 转义
    bluehtt
        4
    bluehtt  
    OP
       2020-10-30 18:20:57 +08:00 via iPhone
    @wlsnx #1 两个方案我都试过了,解决不了
    codehz
        5
    codehz  
       2020-10-30 18:22:27 +08:00 via Android
    (对面开一个 bash -然后本地用文件 pipe 过去
    bluehtt
        6
    bluehtt  
    OP
       2020-10-30 18:26:42 +08:00
    @rizon @Jirajine #2 #3 嗯,是会想到转义 $。你们可能没有看到 $ 里面的命令,转义更复杂,我试了很多都失败了。
    bluehtt
        7
    bluehtt  
    OP
       2020-10-30 18:27:40 +08:00
    @codehz #5 具体如何操作呢?我觉得里面的命令没想的这么简答
    nuk
        8
    nuk  
       2020-10-30 18:31:09 +08:00
    老哥先 echo 一下呀,echo 的结果就是远程执行的命令,当然这个双引号显然也是有问题的。
    codehz
        9
    codehz  
       2020-10-30 18:34:49 +08:00 via Android   ❤️ 1
    @bluehtt 这个就是非常通用的解决方法,适用于任何场景。。。唯一的问题就是多一个文件,但是总比思考转义方便
    把命令按文本写在一个文件里(这里假设名字是 command ),不需要额外的转义,可以有换行。
    然后再执行
    <command ssh user@host "bash -s"
    (<pipe 放哪里都一样,只要和命令本体隔开至少一个空格
    pagxir
        10
    pagxir  
       2020-10-30 18:35:15 +08:00 via Android   ❤️ 1
    CMD=$( cat << 'EOF' docker run -d --name nginx-test $(cat /etc/hosts | grep '^192'| awk '{print "--add-host " $2":"$1}' | awk '{if(NR%900==0){printf $0 "\n"}else{printf "%s ",$0}}') -p 80:80 nginx EOF ) ssh [email protected] $CMD
    pagxir
        11
    pagxir  
       2020-10-30 18:37:35 +08:00 via Android   ❤️ 3
    CMD=$(
    cat << 'EOF'
    docker run -d --name nginx-test $(cat /etc/hosts | grep '^192'| awk '{print "--add-host " $2":"$1}' | awk '{if(NR%900==0){printf $0 "\n"}else{printf "%s ",$0}}') -p 80:80 nginx
    EOF
    )
    ssh user@host $CMD
    lc1450
        12
    lc1450  
       2020-10-30 18:38:48 +08:00   ❤️ 2
    /etc/hosts 这种一般硬射进去好一点吧,方便修改
    bluehtt
        13
    bluehtt  
    OP
       2020-10-30 18:51:09 +08:00
    @lc1450 #12 嗯,文件映射是可以的,但是感觉怪怪的。
    bluehtt
        14
    bluehtt  
    OP
       2020-10-30 18:52:22 +08:00
    @pagxir #11 可以了,多谢。这里的 CMD 是一个临时文件是吗?
    bluehtt
        15
    bluehtt  
    OP
       2020-10-30 18:54:49 +08:00
    @codehz 好的,多谢了。
    codehz
        16
    codehz  
       2020-10-30 19:04:02 +08:00 via Android
    @bluehtt 是一个变量,这是利用 heredoc 特性做的,这么说也不用变量了,结合一下直接

    ssh user@host 'bash -s' <<'这段文字表示分割线,只要不和内容冲突就好'
    任何命令
    这段文字表示分割线,只要不和内容冲突就好

    之前没提这个主要是没想起来 heredoc 也可以禁用内部转义的
    bluehtt
        17
    bluehtt  
    OP
       2020-10-30 19:13:28 +08:00
    @codehz #16 受益匪浅,🙏
    bluehtt
        18
    bluehtt  
    OP
       2022-03-03 09:23:02 +08:00
    测试一下图片评论
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2226 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 00:48 · PVG 08:48 · LAX 16:48 · JFK 19:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.