Linux

shebang or not shebang

  • May 10, 2019

我想在 shebang 中使用一個程序,所以我創建了一個名為 <myscript> 的腳本:

#!&lt;mypgm&gt;

我還希望能夠直接從命令提示符執行 <mypgm>。

&lt;mypgm&gt; args...

到目前為止,沒有問題。

我希望能夠從帶有參數的命令提示符執行 <myscript> 。

&lt;myscript&gt; blabla

反過來,shebang 使用以下參數呼叫 <mypgm>:

&lt;mypgm&gt; &lt;myscript&gt; blabla

現在,我需要知道何時使用 shebang 呼叫 <mypgm> <myscript> blabla,或者不:

myscript blabla # uses the shebang
-or-
&lt;mypgm&gt; myscript blabla   # directly in the command prompt.

我查看了程序表(也是父程序)中的環境變數(編輯:<=== 錯誤斷言(¬,¬”)),但沒有找到任何改變的方法。

到目前為止,我唯一發現的是:

grep nonvoluntary_ctxt_switches /proc/$$/status

當這條線就在 shebang 之後,通過 shebang 呼叫時該值通常為 2(有時為 3),而直接呼叫時該值通常為 1(有時為 2)。由於不穩定並且依賴於程序調度(程序從其 CPU 中移除的次數),我想知道這裡是否有人可能有更好的解決方案。

與其myprg神奇地檢測它是否在 shebang 中使用,為什麼不通過使用命令行標誌(例如-f)將文件作為腳本傳遞給它來明確這一點?

從您在評論中的範例:

在上面的計算理論範例中。 calc PI + 1應該返回 4.14159… 現在添加對 shebang 的支持(即文件名作為第一個參數)將返回包含在文件中的計算。

製作calc一個腳本文件-f,然後使用以下命令創建腳本:

#!/usr/local/bin/calc -f
$1 + 1

假設您呼叫此文件addone.calc並使其可執行。然後你可以呼叫它:

$ ./addone.calc PI
4.141592...

該呼叫將轉換為對 的呼叫/usr/local/bin/calc -f ./addone.calc PI,因此很清楚哪個參數是腳本文件,哪個是腳本的參數。

這類似於方式awksed行為。

一種類似(但相反)的方法是calc預設採用腳本文件參數(這簡化了它與 shebang 的使用),但添加了一個命令行標誌以將其與來自參數的表達式一起使用。這類似於sh -c '...'工作原理。

真正的問題是你設計命令行語法的方式&lt;mypgm&gt;。與其嘗試支持兩種解釋其參數的方式,不如提供兩種呼叫它的方式。

Shebang 命令旨在成為執行腳本內容的腳本引擎;它可能是bash,perl或其他什麼,但期望是使用要執行的腳本的文件名呼叫它。怎麼bash做?它不猜測。如果它遇到任何看起來不像選項的參數(或選項的參數),它會將其視為要執行的腳本;之後的參數被傳遞給腳本。例如:

/bin/bash -x -e somename foo bar

在這裡,bash 將查找該文件somename並嘗試將其作為帶有參數foobar. 你應該做同樣的事情,因為有一天你可能&lt;mypgm&gt; &lt;myscript&gt;在命令行上寫。

如果您希望無腳本使用&lt;mypgm&gt;成為預設值,您可以要求使用 . 傳遞腳本&lt;mypgm&gt; -f &lt;myscript&gt;。這是如何sed做到的。然後你會在這樣的 shebang 行中使用它:

#!&lt;mypgm&gt; -f

如果您希望腳本大小寫為預設值,例如使用bashand perl,請創建一個選項,顯示“這次沒有腳本”。您可以使用--它,這樣&lt;mypgm&gt; -- one two three它就不會嘗試one作為腳本執行(或其他任何東西)。在這種情況下,shebang 行將顯示為:

#!&lt;mypgm&gt;

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