Shell-Script

使用 shebang 使 STDIN 可執行

  • September 28, 2021

我有一個列出數據庫文件的程序。

它從 shell 中被直接稱為

db filename

列出整個文件,或喜歡

db 'filename :: conditions'

僅列出選定的元素…


另一種方法是使用包含所有參數的文件來呼叫它。

db < parameterfile

內容是這樣的(和上面’‘中的內容差不多):

filename
::
conditions

現在我想讓這樣的文件可執行。這樣我就可以打電話了./parameterfile

我認為使用 shebang#!/usr/bin/env db失敗,因為#不是評論標誌。我收到錯誤消息

db - Line 1 near ""#.//r" - " - syntax error

shell returned 26

有沒有單行線可以做到這一點?

您可以編寫一個 shell 腳本來刪除 shebang 行(如果有),並將結果傳遞給db. 將此腳本放在您的PATH. 否則,您可能必須在 shebang 行中指定腳本的完整路徑。使用此腳本作為您的parameterfile.

runparam如果第一行是 shebang 行,則刪除第一行的範例腳本:

#!/bin/sh
awk 'FNR>1 || ! /^#!/' "$@" | db

範例parameterfile

#!/usr/bin/env runparam
filename
::
conditions

你可以執行它

./parameterfile

在這種情況下,腳本可以假設總會有一個 shebang 行。

您也可以使用與呼叫相同的方式直接使用參數文件呼叫腳本db,但這沒有任何優勢。

runparam parameterfile
runparam parameterfile1 parameterfile2 [...]
runparam < parameterfile

如果您永遠不會runparam使用不包含 shebang 行的文件進行呼叫,則可以使用tail而不是awk無條件地刪除第一行。這可能會更快。

#!/bin/sh
tail -n+2 | db

使用 awk 作為 shebang 包裝器:

#! /usr/bin/awk BEGIN{getline;cmd="db"}{print|cmd}END{exit(close(cmd))}

... "db" commands here ...

如果您的腳本應該直接通過execve(2)但只能通過 shell(或通過類似的命令find -exec)執行,那麼您有更多選擇,包括使其可執行而不預先添加 shebang,並將其保留為任何語言的有效命令腳本該db命令理解。這完全取決於該語言是什麼。例如,如果該語言中的註釋行以//(如在 C++ 中)開頭,則可以使用:

// 2>/dev/null; exec db "$0" "$@"

... "db" commands here ...

引用自:https://unix.stackexchange.com/questions/670448