如何將管道輸入傳遞給別名中的第二個命令?

如何將管道輸入傳遞給別名中的第二個命令?

我定義了一個別名,例如:

alias xyz='command1; command2'

我想將另一個命令 pqr 的輸出透過管道傳輸到 command2,例如:

pqr | xyz -f -

是否可以?我怎樣才能做到這一點?

答案1

使用別名通常是不是非互動式 shell 腳本的良好實踐(Bash常見問題/080)。您在 OP 中定義別名的方式,只有第一個命令從標準輸入讀取,因為;會終止您的標準輸入超出第一個命令。

一種可能的方法是使用 進行命令分組{..},以便任何重定向都適用於群組內的整個命令集。您仍然可以保留您的alias定義並執行

alias xyz='{ command1; command2; }'

在這種情況下,您comamnd1不必要地獲得標準輸入的副本。您可以透過執行以下操作來關閉它

alias xyz='{ command1 < /dev/null ; command2 - ; }'

或使用函數來定義您的命令。

xyz() {
    command1; command2
}

如果您的 shell支援進程bash替換zsh,您只需定義command2接收 stdin 內容作為位置參數。將您的函數重新定義為

xyz() {
    command1
    command2 "$@"
}

然後呼叫你的命令 ( pqr) 作為

xyz < <(pqr)

上面的一個簡單的演示,

zoo() { date; sed 's/foo/boo/' "$@"; }
zoo < <(echo food)                     #(or) zoo <<<"food"
Mon Nov 25 02:44:49 EST 2019
bood

答案2

我建議您嘗試 xargs 方法,即:

alias xyz='command1; command2 | xargs pqr'

這相當於以輸入參數pqr運行command2

答案3

command2將某些內容傳遞到命令清單的標準輸入中

command1; command2

您必須確保command1不從標準輸入讀取。這可以透過將標準輸入重定向到來/dev/null完成command1

command1 </dev/null; command2

這給你留下了別名

alias xyz='command1 </dev/null; command2`

你會的不是能夠打電話給

pqr | xyz -f -

因為那相當於

pqr | command1 </dev/null; command2 -f -

這與以下相同

pqr | command1 </dev/null
command2 -f -

相反,定義xyz為 shell 函數:

xyz () {
    command1 </dev/null
    command2 "$@"
}

在這裡,command2將獲取函數的標準輸入以及提供給函數的任何命令列參數。

現在您可以像在管道中一樣使用它pqr | xyz -f -

如果(且僅當)-f -您傳遞給的參數command2是「從標準輸入讀取」(表示-標準輸入),那麼您可以不-將進程替換傳遞給xyz,如果您的 shell 支援的話:

xyz -f <(pqr)

使用上面的函數,這與執行相同

command1 </dev/null
command2 -f <(pqr)

相關內容