shebang or not shebang
我想在 shebang 中使用一個程序,所以我創建了一個名為 <myscript> 的腳本:
#!<mypgm>
我還希望能夠直接從命令提示符執行 <mypgm>。
<mypgm> args...
到目前為止,沒有問題。
我希望能夠從帶有參數的命令提示符執行 <myscript> 。
<myscript> blabla
反過來,shebang 使用以下參數呼叫 <mypgm>:
<mypgm> <myscript> blabla
現在,我需要知道何時使用 shebang 呼叫 <mypgm> <myscript> blabla,或者不:
myscript blabla # uses the shebang -or- <mypgm> 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
,因此很清楚哪個參數是腳本文件,哪個是腳本的參數。這類似於方式
awk
和sed
行為。一種類似(但相反)的方法是
calc
預設採用腳本文件參數(這簡化了它與 shebang 的使用),但添加了一個命令行標誌以將其與來自參數的表達式一起使用。這類似於sh -c '...'
工作原理。
真正的問題是你設計命令行語法的方式
<mypgm>
。與其嘗試支持兩種解釋其參數的方式,不如提供兩種呼叫它的方式。Shebang 命令旨在成為執行腳本內容的腳本引擎;它可能是
bash
,perl
或其他什麼,但期望是使用要執行的腳本的文件名呼叫它。怎麼bash
做?它不猜測。如果它遇到任何看起來不像選項的參數(或選項的參數),它會將其視為要執行的腳本;之後的參數被傳遞給腳本。例如:/bin/bash -x -e somename foo bar
在這裡,bash 將查找該文件
somename
並嘗試將其作為帶有參數foo
和bar
. 你應該做同樣的事情,因為有一天你可能想<mypgm> <myscript>
在命令行上寫。如果您希望無腳本使用
<mypgm>
成為預設值,您可以要求使用 . 傳遞腳本<mypgm> -f <myscript>
。這是如何sed
做到的。然後你會在這樣的 shebang 行中使用它:#!<mypgm> -f
如果您希望腳本大小寫為預設值,例如使用
bash
andperl
,請創建一個選項,顯示“這次沒有腳本”。您可以使用--
它,這樣<mypgm> -- one two three
它就不會嘗試one
作為腳本執行(或其他任何東西)。在這種情況下,shebang 行將顯示為:#!<mypgm>