有些bash指令碼寫的不規範,沒有在檔案開頭寫#!,但是卻能直接執行,可是如果看核心**,shell指令碼的載入函式中的開頭就會判斷,如果沒有#!的話就會返回錯誤:
static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
為何在linux上寫bash指令碼時檔案開頭不寫#!也能成功呼叫?bash中執行一條鍵盤命令時呼叫的是shell_execve函式,該函式封裝了很多邏輯:
int shell_execve (command, args, env)
else
...//bash會幫你執行command:
/*args[0] = shell_name; //就是本shell的全路徑
args[1] = command; //要執行的指令碼
execve (shell_name, args, env); //重新執行*/}
以下是上述shell_execve函式依賴的幫助函式和一些巨集定義:
由於bash是通過字元的可見性來判斷是否是二進位制檔案的,由於空格/製表符等也是不可見的字元,然而它們確實是屬於文字ascii碼的,因此需要單獨進行過濾:
#define isspace(c) ((c) == ' ' || (c) == '/t' || (c) == '/n' || (c) == '/f')
文字字元包括字母字元,數字字元以及除此之外的可以列印字元:
#define isprint(c) (isletter(c) || digit(c) || ispunct(c))
判斷讀取的80個位元組是否全部是文字字元,只要有乙個不是就將該檔案判定為二進位制檔案,雖然前80位元組的字元是文字不能保證後面的就一定是文字,可是bash畢竟需要做出乙個權衡和乙個假設:
int check_binary_file (sample, sample_len)
return (0);
}因此如果執行乙個空檔案,將會看到什麼也不輸出,如果執行乙個非linux可執行的二進位制檔案比如cer格式的二進位制證書,那麼核心將返回enoexec,接下來bash會嘗試執行之,然後最終返回乙個ex_binary_file錯誤,列印「cannot execute binary file」,如果執行乙個檔案頭不是#!的文字檔案,同樣核心會返回乙個enoexec錯誤,但是bash卻可以在shell_execve的後續執行中成功直接執行,可是如果在乙個二進位制檔案的頭部增加80位元組或者80位元組以上的文字,那麼根據shell_execve的邏輯,bash也會將之作為指令碼來分行執行,然後就會大錯特錯,因此雖然有的時候指令碼中不寫#!也能直接執行,但是要知道那可是bash本身幫你執行的,而不是核心直接執行的,起碼執行緒會先從核心錯誤返回,然後繼續shell_execve的後面的部分,確實稍微影響了效率,因此最好還是寫上標準的#!,況且有的shell並不會像bash這麼智慧型地重新解釋執行命令。
bash指令碼執行的控制語句
一 bash指令碼執行的控制語句 1 順序執行 預設,逐條執行各語句。2 選擇執行if 分支,條件判斷,執行符合條件的分支。2 雙分支 fi 3 多分支 4 例1 寫乙個指令碼,實現如下功能 1 讓使用者通過鍵盤輸入乙個使用者名稱 2 如果使用者存在,就顯示其使用者名稱和uid 3 否則,就顯示使用...
bash指令碼併發執行
目錄背景 採用gnu的paralle程式 並行化方法 wait 缺點 程序數可控的並行化方法 命名管道 在linux下執行作業時,經常會遇到以下情形 有大量作業需要執行,完成每個作業所需要的時間也不是很長.如果我們以序列方式來執行這些作業,可能要耗費較長的時間 若採用並行方式執行則可以大大節約執行時...
批量Ping執行Bash指令碼
bin bash ping batch script 連線超時時間 tmout 3 最大執行緒數 max thread 4000 保留記憶體大小 min mem 400 預設ip配置,可通過 r ip ip指定,格式 ping batch.sh r 192.168.1.1 192.168.2.254...