从脚本内部执行命令时为什么命令失败?

时间:2020-04-01 03:52:25

标签: linux bash shell ssh

我正在尝试通过bash脚本将所有内容从远程文件夹复制到本地计算机中:

    #!/usr/bin/env bash

    REMOTE_SOURCE="/absolute/path/to/source/data"
    TARGET="/absolute/local/path/to/target"
    SSH="ssh myuser@myhost"

    cd $TARGET
    echo $PWD

    TRANSFER="$SSH -- 'cd $REMOTE_SOURCE; tar cz ./' | tar xz"

    echo $TRANSFER
    $TRANSFER

在传输命令存储在变量中的情况下运行脚本失败,

bash:cd / absolute / path / to / source / data; tar cz ./:没有这样的文件或目录

echo $TRANSFER复制输出并将直接运行到外壳中时,它可以正常工作:

ssh myuser@myhost -- 'cd /absolute/path/to/source/data; tar cz ./' | tar xz

注意:

  • 当然存在远程文件夹,所以报告的错误令人困惑,并且无助于我了解要解决的问题。
  • 我也删除了tar cz ./部分,只留下了cd命令。

更新:

删除'引号可使命令起作用。

但是然后如何将ssh结果传送到tar xz 中?

解决方案:

该脚本应尽量减少引用,避免过多的变量扩展魔术:

echo "$SSH -- \"cd $REMOTE_DATA; tar cz ./  \" | tar xz"
$SSH -- "cd $REMOTE_DATA; tar cz ./" | tar xz

1 个答案:

答案 0 :(得分:0)

Bash支持数组,您会遇到引号问题(并且运行完全不加引号的操作会导致意外混乱)。

我们将其更新为使用数组:

import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

public class WebSocketListenerImpl extends WebSocketListener {

    public WebSocketListenerImpl() {
        super();
    }

    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        super.onOpen(webSocket, response);
        print "WEBSOCKET OPEN"
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
        super.onMessage(webSocket, text);
        print "WEBSOCKET RECEIVED"

    }

    @Override
    public void onMessage(WebSocket webSocket, ByteString bytes) {
        super.onMessage(webSocket, bytes);
        print "WEBSOCKET OPEN"

    }

    @Override
    public void onClosing(WebSocket webSocket, int code, String reason) {
        super.onClosing(webSocket, code, reason);
        print "WEBSOCKET CLOSING"

    }

    @Override
    public void onClosed(WebSocket webSocket, int code, String reason) {
        super.onClosed(webSocket, code, reason);
        print "WEBSOCKET CLOSED"

    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, @javax.annotation.Nullable Response response) {
        super.onFailure(webSocket, t, response);
        println "WEBSOCKET FAILED"

    }
}

这需要一个额外的变量,因为您不能在不加引号的情况下将#!/usr/bin/env bash REMOTE_SOURCE="/absolute/path/to/source/data" TARGET="/absolute/local/path/to/target" SSH="myuser@myhost" cd "$TARGET" echo "$PWD" TRANSFER=(ssh "$SSH" -- "cd $REMOTE_SOURCE; tar cz ./") AFTER=(tar xz) echo "${TRANSFER[@]} | ${AFTER[@]}" "${TRANSFER[@]}" | "${AFTER[@]}" 放在其中,这会阻止它按照您的期望进行操作。