1. cielavenir

    Posted

    cielavenir
Changes in title
+外部プログラムを直接実行した場合にシェルスクリプトにフォールバックする言語・しない言語
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,54 @@
+※本記事の内容はWindowsには一切当てはまりません。
+
+https://linuxjm.osdn.jp/html/LDP_man-pages/man3/exec.3.html 等によると、execvpでのみ、ENOEXECが発生したらシェルスクリプトと解釈する機能があるそうです。
+スクリプト言語でシェルを使わず外部プログラムを実行した場合、この機能は働くのでしょうか?
+
+## 準備
+
+```
+$ cat lsscript
+ls
+```
+
+## 実行
+
+### Ruby
+
+- 直接実行(例): popenの引数が配列
+- `ruby -e 'p IO.popen(["./lsscript"]).read'`
+
+process.c proc_exec_cmd
+execveを試し、ENOEXECなら/bin/shを付加して再試行
+
+### Python
+
+- 直接実行(例): check_call(等)の引数が配列
+- `python -c 'import subprocess;subprocess.check_call(["./lsscript"])'`
+
+Modules/_posixsubprocess.c child_exec
+execveを試す。 **ENOEXECの場合失敗する**
+
+Python3も同様。
+なおshell=Trueとすると失敗しなくなりますがpipes.quoteやらshlex.quoteやらが必要となります。
+
+### Perl
+
+- 直接実行(例): system()の引数が2以上
+- `perl -e 'print system("./lsscript","dummy")'`
+
+doio.c Perl_do_aexec5
+execvpを試す。
+
+### PHP
+
+- 直接実行: pcntl_exec
+- `php -r 'pcntl_exec("./lsscript");'`
+
+ext/pcntl/pcntl.c pcntl_exec
+execveを試す。 **ENOEXECの場合失敗する**
+
+(上はexecですからサブプロセスとするにはfork呼び出し等が必要。その辺が必要ない標準実行系はext/standard/exec.cにありますが、popen固定のようです(つまり必ずシェルが入る))
+
+## 結論
+
+Python/PHPでシェルを介さずに実行しようとすると、自動でshを付けてくれません。[C言語のshebangもどき](https://qiita.com/cielavenir/items/6063c117f25f9188b84c)等を投げる際はご注意ください。