Linux shell中&,&&,|,||的用法
前言
在玩dvwa的命令註入漏洞的時候,遇到了沒有預料到的錯誤,執行
ping 127.0.0.1 & echo "<?php phpinfo(); ?>" > shell.php
發現返回的執行結果如下圖
理論上在dvwa的根目錄裏應該有一個shell.php但是並沒有出現
root@kali:/var/www/html/dvwa# ls about.php docs hackable login.php README.md test.php CHANGELOG.md dvwa ids_log.php logout.php robots.txt vulnerabilities config external index.php phpinfo.php security.php COPYING.txt favicon.ico instructions.php php.ini setup.php root@kali:/var/www/html/dvwa#
原因
經幾次嘗試,發現問題出在&
上。將其換成|
就可以完成寫入shell,但是對& && | ||
的功能不是很了解,於是在Linux終端嘗試了一下,基本上搞清楚了涵義和用法
看結論請直接拉到最後點這裏
嘗試過程
使用了一個Linux命令sleep,輸入sleep --help
顯示幫助,系統給出的介紹如下:
root@kali:~# sleep --help Usage: sleep NUMBER[SUFFIX]... or: sleep OPTION Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days. Unlike most implementations that require NUMBER be an integer, here NUMBER may be an arbitrary floating point number. Given two or more arguments, pause for the amount of time specified by the sum of their values. --help 顯示此幫助信息並退出 --version 顯示版本信息並退出 root@kali:~#
其余的是簡單的ifconfig、uname和echo命令
還有一條設定:cmd1 操作符 cmd2 操作符 cmd3 ......
,把整個稱作一個命令
&
執行ifconfig & echo hello
,返回的執行結果如下:
這個結果有一些值得註意的點,一是奇怪的[1] 3187
,二是先顯示的hello(執行了echo),再另起一行顯示了ifconfig的結果,按說應該是先執行ifconfig顯示網絡配置信息,接著才應該執行echo,三是最後的已完成,這與平常命令執行結束明顯的不同
執行echo hello & ifconfig
,返回的執行結果如下:
對比上個命令的執行結果,有很多不同。這個結果貌似是符合我們的預期的,先執行了echo再執行了ifconfig,但是還有莫名的方框數字和已完成
上網以關鍵詞linux &
查詢到,在Linux下,命令之後加上&
,表示把該命令以後臺方式執行。其中,[1]
表示後臺任務的標識,之後的數字表明後臺執行的任務的UID,那就意味著shell將這個後臺命令以多進程的方式在運行。
於是猜想cmd1 & cmd2
執行的方式是以後臺方式執行cmd1,同時執行cmd2。驗證如下:
echo命令執行較快,於是首先輸出了hello,sleep強制停止了5秒,於是在後臺顯示在運行中,5秒之後完成。
&&
&
沒有邏輯功能,那麽猜想&&
真正完成了邏輯與的功能,從左到右依次執行各項命令
動態效果不好演示,可以通過輸入sleep 5 && echo ends
看一下動態的效果。執行的結果確實是暫停了5秒,之後顯示了ends
但是還可以以其他方式表現,譬如如下的命令
很明顯的證明cmd1和cmd2的執行順序關系
此時應有補充資料:
shell 在執行某個命令的時候,會返回一個返回值,該返回值保存在 shell 變量 $? 中。當 $? == 0 時,表示執行成功;當 $? != 0 時,表示執行失敗。
這篇博文詳細的列出了Linux裏的返回值,供參考
由編程的知識很容易理解,0&&!0 ==0
,這樣,任意一個cmd出現了錯誤,只要有可以正確執行返回0的cmd,整體命令返回值就是0,將不會影響到其他cmd的執行,只會單獨關於某個錯誤的cmd報一個錯誤
|
鑒於&
不表示邏輯與,那麽|
也不一定表達邏輯或的含義,實驗一下命令
發現第一條命令輸出了hello,同時命令並沒有終止,光標等待了5秒之後,才另起一行。這表明兩個子命令一起被執行,但是與&
不同,cmd1被放在前臺執行。可以推斷shell將cmd1和cmd2分為兩個線程執行。
發現第二條命令沒有顯示ifconfig應有的輸出,但是如下圖所示:
可以看到,cmd1實際上已經被執行了,只是返回的信息沒有被顯示在終端上
那麽可以總結出,cmd1 | cmd2
中,cmd1和cmd2同時在前臺被執行,但是cmd1的執行結果不會被顯示在終端上。
||
跟&&類似,cmd之間使用||
接,從而實現邏輯或的功能
實驗如下命令:
只有在||
左邊的命令返回假(命令返回值 $? != 0),||
右邊的命令才會被執行。這和 c 語言中的邏輯或語法功能相同,(0||!0 == 0),即實現短路邏輯或操作。同時,只要有一個命令返回真(命令返回值 $? == 0),後面的命令就不會被執行,直到返回真的地方停止執行。
總結
再看一下設定:cmd1 操作符 cmd2 操作符 cmd3 ......
,把整個稱作一個命令
&
:除了最後一個cmd,前面的cmd均已後臺方式靜默執行,執行結果顯示在終端上,個別的cmd錯誤不影響整個命令的執行,全部的cmd同時執行
&&
:從左到右順序執行cmd,個別cmd錯誤不產生影響
|
:各個cmd同時在前臺被執行,但是除最後的cmd之外,其余的執行結果不會被顯示在終端上
||
:從左到右順序執行cmd,只有左側的cmd執行出錯,右邊的cmd才會被執行,同時一旦有cmd被成功執行,整個命令就會結束,返回終端
Linux shell中&,&&,|,||的用法