Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2862

シバン(shebang)にシェル以外のコマンドを指定してシバンの動作を確かめてみる

$
0
0
今回の動作確認環境 Vagrant 2.2.14 CentOS 8 bash 4.4.19 shebangで指定可能な形式について shebangとは実行可能権限が付与されたシェルスクリプトの先頭行に書かれている #!/bin/sh の部分のことを指します。 シェルスクリプトでよく見かける形式としては、以下のようなものではないでしょうか。 #!/bin/sh #!/usr/bin/bash スクリプト言語を利用する方であれば、こういった形式で書かれているかと思います。 #!/usr/bin/perl #!/usr/local/bin/ruby #!/usr/bin/env python3 /usr/bin/perl や /usr/bin/env からわかるように、 /etc/shells に記載されているようなシェルのパス以外の実行ファイルでも指定できることに気づきます。 Wikipediaによると shebang として指定可能なのは「the file specified by interpreter must be an executable binary and cannot itself be a script.」とのこと。 つまり、実行可能なバイナリファイルで、shebangを書いてるシェルスクリプト自身以外であればOKみたいです。 Wikipedia内にexecveのマニュアルページへの参照リンクが貼られていたので man execve を見てみると以下のように DESCRIPTION に記述されていました。 DESCRIPTION execve() executes the program pointed to by filename. filename must be either a binary executable, or a script starting with a line of the form: #! interpreter [optional-arg] shebang に指定できるのは、以下のいずれかのようです。 実行可能なバイナリ 「#!」で始まるシェルスクリプト 「1」については「/usr/bin/bash」、「/usr/bin/perl」、「/usr/bin/env」といった記述から理解できます。 「2」については、ちょっと試してみましょう。 vagrantユーザのホームディレクトリ直下に like_echo.sh という第1引数をechoするシェルスクリプトを準備して、実行権限を付与します。 $ pwd /home/vagrant $ cat like_echo.sh #!/bin/bash echo $1 $ chmod +x like_echo.sh like_echo.sh に arg1 を渡して呼び出す call_like_echo.sh を準備して、これにも実行権限を付与します。 $ cat call_like_echo.sh #!/home/vagrant/like_echo.sh arg1 $ chmod +x call_like_echo.sh 実行してみると arg1 が出力されました。これで「or a script starting with a line of the form:〜」の部分の検証ができたかと思います。 $ ./call_like_echo.sh arg1 ちなみ call_like_echo.sh でshebang 行で渡す引数の数を増やすとこんな動きになります。 引数を2つ渡して実行。 $ cat call_like_echo.sh #!/home/vagrant/like_echo.sh arg1 arg2 $ ./call_like_echo.sh arg1 arg2 引数を3つ渡して実行。 $ cat call_like_echo.sh #!/home/vagrant/like_echo.sh arg1 arg2 arg3 $ ./call_like_echo.sh arg1 arg2 arg3 この動きから like_echo.sh で受け取った $1 には call_like_echo.sh の shebang 行で指定した「arg1 arg2 arg3」の部分すべてが第1引数として扱われているようです。 echoで実行状況を可視化 ここまでで shebang には /bin/sh のようなシェル以外でも man execve に記載されている条件を満たしていれば指定できることがわかりました。 また、さきほどの like_echo.sh の動作から、 shebang で #!/bin/bash と指定すると、以下のような呼び出され方をしていることがわかります。 $ /bin/bash like_echo.sh 引数 当然と言えば当然の動きなんですが。。。この動きを echo コマンドを使って可視化してみましょう。 shebang に echo コマンドのパスを記述して、実行権限を付与します。 $ cat echo.sh #!/usr/bin/echo $ chmod +x echo.sh 実行すると、シェルスクリプト自体のファイル名が出力されました。 $ ./echo.sh ./echo.sh ということは shebang 行に #!/usr/bin/echo と指定することで、実際にはこのように呼び出されたことがわかります。 $ /usr/bin/echo ./echo.sh 引数を渡してみると /usr/bin/echo ./echo.sh 引数 のように呼び出されていることが可視化できていますね。 引数が1つの場合。 $ ./echo.sh arg1 ./echo.sh arg1 引数が2つの場合。 $ ./echo.sh arg1 arg2 ./echo.sh arg1 arg2 wcで行数を数えてみる shebangで指定したコマンド ./自身のファイル名 引数 の形式でシェルスクリプトが実行されることがわかったので、この仕組みを使ってファイルの行数を数えてみます。 こんなファイルを準備して、実行権限を付与します。 $ cat wc.sh #!/usr/bin/wc -l # Comment1 # Comment2 # Comment3 # Comment4 # Comment5 $ chmod +x wc.sh 実行するとファイルの行数が出力されました。 $ ./wc.sh 6 ./wc.sh cpでシェルスクリプトのコピーを作成する こうなってくると、自身のファイル名を使った操作が色々と可能ですね。 ファイルのコピーを行うスクリプトを準備して、実行権限を付与します。 $ cat cp.sh #!/usr/bin/cp $ chmod +x cp.sh 引数に cp.sh.YYYYMMDDHHMMSS 形式のファイル名を渡すと cp.sh がコピーされて cp.sh.20210711042853 が作成されました。 $ ./cp.sh cp.sh.`date '+%Y%m%d%H%M%S'` $ ls -l cp.sh.20210711042853 -rwxrwxr-x. 1 vagrant vagrant 14 Jul 11 04:28 cp.sh.20210711042853 まとめ shebang は「実行可能なバイナリ」もしくは「#!で始まるシェルスクリプト」が指定できる。 shebang に #!/PATH/TO/コマンド コマンドの引数 と記述して ./シェルスクリプト名 シェルスクリプトの引数 のように実行すると、実際には /PATH/TO/コマンド コマンドの引数 ./シェルスクリプト名 シェルスクリプトの引数 のような形式で実行されている。 参考URL シバン(shebang)にスクリプトを実行しないコマンドを指定してみる実験 シェルスクリプトのシバン(Shebang)にシェル以外のコマンドを記述したらどうなるのか? 作業の自動化、謎のおまじない shebang(シバン)、PATH を設定する What is shebang (#!/bin/sh) in POSIX shell script シェルのshebang が実行されるときの引数を見てみる。 shebangから理解するUNIXの仕組み /bin/shと/bin/bashの違い(とcronでのシェル) スクリプト言語 C —— shebangのないテキストファイルはいかに実行されるか PythonスクリプトからShebangの意味を考えてみる Perl, Python 及び Ruby スクリプトにおける正しいshebangの書き方 シェルスクリプトの冒頭でbashを明示する(提案) #!/bin/sh は ただのコメントじゃないよ! Shebangだよ! bash スクリプトの先頭によく書く記述のおさらい 手を動かして理解するshebang シバン (shebang) を書いた方が可搬性が高いシェルスクリプトになる shebang

Viewing all articles
Browse latest Browse all 2862

Trending Articles