inux shell有交互式與非交互式兩種工作模式。我們日常使用shell輸入命令得到結果的方式是交互式的方式,而shell腳本使用的是非交互式方式。
shell提供了alias功能來簡化我們的日常操作,使得我們可以為一個復雜的命令取一個簡單的名字,從而提高我們的工作效率。在交互式模式下,shell的alias擴展功能是打開的,因此我們可以鍵入自己定義的alias別名來執行對應的命令。
但是,在非交互式模式下alias擴展功能默認是關閉的,此時仍然可以定義alias別名,但是shell不會將alias別名擴展成對應的命令,而是將alias別名本身當作命令執行,如果shell內置命令和PATH中均沒有與alias別名同名的命令,則shell會“抱怨”找不到指定的命令。
那么,有沒有辦法在非交互式模式下啟用alias擴展呢?答案是使用shell內置命令shopt命令來開啟alias擴展選項。shopt是shell的內置命令,可以控制shell功能選項的開啟和關閉,從而控制shell的行為。shopt的使用方式如下:
shopt -s opt_name Enable (set) opt_name. shopt -u opt_name Disable (unset) opt_name. shopt opt_name Show current status of opt_name.
alias擴展功能的選項名稱是expand_aliases,我們可以在交互式模式下查看此選項是否開啟:
sw@gentoo ~ $ shopt expand_aliases expand_aliases on sw@gentoo ~ $
可見在交互式模式下alias擴展功能的確是開啟的,因此我們才能使用alias別名。
我們編寫一個腳本來驗證一下非交互式模式下alias擴展的設置:
#!/bin/bash --login alias echo_hello="echo Hello!" shopt expand_aliases echo_hello shopt -s expand_aliases shopt expand_aliases echo_hello
腳本執行結果如下:
sw@gentoo ~ $ ./test.sh expand_aliases off ./test.sh: line 5: echo_hello: command not found expand_aliases on Hello! sw@gentoo ~ $
可以看到,在非交互式模式下alias擴展功能默認是關閉的,但是我們可以用shopt來將其開啟。
另外,alias別名只在當前shell有效,不能被子shell繼承,也不能像環境變量一樣export。可以把alias別名定義寫在.bashrc文件中,這樣如果啟動交互式的子shell,則子shell會讀取.bashrc,從而得到alias別名定義。但是執行shell腳本時,啟動的子shell處於非交互式模式,是不會讀取.bashrc的。
不過,如果你一定要讓執行shell腳本的子shell讀取.bashrc的話,可以給shell腳本第一行的解釋器加上參數:
#!/bin/bash --login
--login使得執行腳本的子shell成為一個login shell,login shell會讀取系統和用戶的profile及rc文件,因此用戶自定義的.bashrc文件中的內容將在執行腳本的子shell中生效。
還有一個簡單的辦法讓執行腳本的shell讀取.bashrc,在腳本中主動source ~/.bashrc即可。
注:
現在 bash 得加上 `-i` 參數就會變成交互式了,即:
#!/bin/bash -i