簡體   English   中英

將 bash shell 腳本的輸出作為 shell 命令運行?

[英]Running the output of a bash shell script as a shell command?

我有一個名為 'test.sh' 的 shell 腳本:

#!/usr/bin/env bash

echo "echo 'hello';"

當我運行./test.sh它顯然給出了這個輸出:

echo '你好';

現在這個輸出也是一個有效的 shell 語句本身。 如果我將此行復制並粘貼到外殼上並按 Enter,它會顯示

你好

到現在為止還挺好。
但我想一步完成,所以我嘗試了這個:

$(./test.sh)

但是我現在得到:

'你好';

以防萬一,我使用的是 macOS 10.15.6 Catalina,它默認使用zsh shell。 我在 Linux 上使用 bash 嘗試了同樣的方法,結果相同。

我也試過$('./test.sh')$("./test.sh")以防萬一,但顯然這沒有區別。

對此可能有一些簡單的解釋和解決方案,但我看不到。 我究竟做錯了什么?


(編輯)也許這兩個回聲令人困惑,假設我的 test.sh 腳本包含以下內容:

echo "ls *.txt;"

如果我現在做./test.sh我得到

ls *.txt;

如果我將其復制並粘貼到 shell 上,它會按預期顯示所有 .txt 文件。

但是,如果我執行$(./test.sh)我得到:

ls: *.txt;: 沒有那個文件或目錄

將 test.sh 腳本輸出作為 shell 命令行執行的正確語法是什么?

問題是命令替換( $( )事情)是在解析命令行的過程中完成的——在解析並應用引號、分號和其他一些東西之后。 結果,當這些引號、分號等成為命令行的一部分時,它們做任何有用的事情都為時已晚,它們只是沒有特殊含義的普通字符。

這是您真正想要使用eval少數情況之一:

eval "$(./test.sh)"

eval所做的是對其參數重新運行整個解析過程,因此它們中的任何 shell 語法(引號、分號等)都會被完全解析。 雙引號是為了防止在命令替換之后但在結果傳遞給eval之前發生的一點點解析,這可能會導致奇怪的效果。

順便說一句, eval名聲通常很差,因為它可能導致您不希望被視為 shell 語法的東西(如文件名等)被視為 shell 語法。 但在這種情況下,這似乎正是您想要和期望的,所以就是這樣。

你有一個額外的echo 這是代碼(test.sh):

#!/bin/bash
echo "hello"

然后像這樣運行它: $(./test.sh)"$(./test.sh)" 它將啟動hello命令。 如果您希望test.sh運行腳本,請在test.sh使用echo "./hello" (帶有./ )。

要在執行前顯示命令,請使用bash -x test.sh運行此命令

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM