![](/img/trans.png)
[英]Why can the execve system call run “/bin/sh” without any argv arguments, but not “/bin/ls”?
[英]Why doesn't “/bin/sh ls” execute ls?
我是 shell 新手,抱歉,如果我的問題太基本了。我正在使用 Bash shell,下面是我嘗試過的不同觸發命令的方法:
ls // of course it works :)
/bin/sh ls // error, ")" unexpected
/bin/sh -c ls // work just like `ls`
那么為什么/bin/sh ls
不起作用? 是不是當我使用ls
, ls
是/bin/
目錄中的一個可執行對象,所以ls
應該與/bin/sh ls
,不是嗎?
為什么 /bin/sh ls 不起作用?
來自posix 手冊 sh 的一些相關部分:
sh [-abCefhimnuvx] [-o 選項]... [+abCefhimnuvx] [+o 選項]... [command_file [參數...]]
sh -c [-abCefhimnuvx] [-o 選項]... [+abCefhimnuvx] [+o 選項]... command_string [command_name [參數...]]
sh -s [-abCefhimnuvx] [-o 選項]... [+abCefhimnuvx] [+o 選項]... [參數...]
sh 實用程序是一個命令語言解釋器,它將執行從命令行字符串、標准輸入或指定文件讀取的命令。 應用程序應確保要執行的命令以外殼命令語言中描述的語言表示。
-c 從 command_string 操作數讀取命令。 [...]
-s 從標准輸入讀取命令。
如果沒有操作數且未指定 -c 選項,則應假定為 -s 選項。
command_file包含命令的文件的路徑名。 [....]
這:
/bin/sh ls
案例屬於sh command_file
案例。 然后命令文件應該包含由 shell 解釋的 shell 命令。 但是ls
很可能是 ELF 可執行格式的可執行文件 - 遠不及換行符分隔的 shell 命令 - 所以 shell 退出時出現解析器錯誤。
是不是當我使用 ls 時,ls 是 /bin/ 目錄中的一個可執行對象,所以 ls 應該與 /bin/sh ls 相同,不是嗎?
不。
在 shell 中以不同方式調用命令時不一致?
不。通常解釋器和編譯器的編寫方式是將文件傳遞給它們。 當您將文件傳遞給解釋器或編譯器時,例如執行gcc file.c
您希望file.c
是用 C 編程語言編寫的,並且它將被編譯為可執行文件。 當你編寫python file
- 那么file
應該是用 python 編程語言編寫的。 以同樣的方式,當您編寫sh file
,無論sh file
是什么,(在現代/POSIX 操作系統上)都希望以包含 POSIX 兼容 shell 命令的 POSIX sh shell 語言編寫,而不是 shell 命令本身。
/bin/sh ls
導致sh
打開ls
並逐行讀取它以執行 shell 命令。
/bin/sh -c ls
使sh
執行命令行ls
。
在某種意義上,你可以認為/bin/sh ls
等同於
/bin/sh -c 'while IFS= read -r line; do eval "$line"; done < ls'
/bin/sh
期望獲得一個腳本文件作為參數(當沒有更多選項時),即包含 Shell 命令的文本文件。 ls
是一個二進制文件,Shell 無法讀取解釋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.