LoginSignup
0
2

More than 5 years have passed since last update.

スクリプト言語を bash スクリプトに埋め込むためのメモ2

Last updated at Posted at 2017-07-01

断捨離

随分前に書いた、コレに続いて。

あ、Windows での挙動には触れない。

perlとruby

A
$ cat hoge.pl
#!/bin/bash
find . -type f | perl -x $0
exit 0

#!/usr/bin/env perl -ln
print ;

$ perl hoge.pl
./bar
./foo
./hoge
.
.
.

1. perl は、インタプリタを解釈してくれる。

 #! 行に "perl" や "indir" という語が含まれていなければ、#! の後に 指定されたプログラムが Perl インタプリタの代わりに実行されます。 これは少し変わっていますが、#! が行なえないマシンを使っている方には 有効でしょう; プログラムに対して使っている SHELL が /usr/bin/perl だと 言っておけば、Perl が正しいインタプリタを起動してくれるからです
(perlrunより引用)

つまり、

$ cat hoge.rb
#!/usr/bin/env ruby
puts("ruby")
$ perl hoge.rb
ruby
$ cat hoge.sh
#!/bin/bash
echo bash
$ perl hoge.sh
bash

2. ruby は、インタプリタが複数書かれてたら、ruby まで読み飛す。

コマンドラインに指定したスクリプトが #! で始まるファイルで、その行に ruby という文字列を含まない場合、その行を読み飛ばします。#! に続く 文字列が ruby という文字列を含む行を見つけたらその行以下を Ruby スク リプトとして実行します。
(rdocより引用)

B
$ cat hoge2.sh
#!/bin/bash
echo bash
ruby -x $0
exit 0
#!/usr/bin/env ruby
puts("ruby")

の場合、

$ ruby hoge2.sh
ruby

3. perl も ruby も -x によって、解析開始を遅らす事が出来る。

-x スイッチを 指定した場合には、まず、最初に #! と "perl" という文字列を 含む行を探し、そこから解析を始めます。 これは、大きなテキストにプログラムを埋め込んで、実行するようなときに便利です。 (この場合、プログラムの終わりは、トークン END を使って 示すとよいでしょう。)

(perlrunより引用)

ruby の方も rdoc に同様の事が明記してある。

てなわけで、A のコードが成立する。

ruby の B でも

Bをbashで実行する。
$ bash hoge2.sh
bash
ruby

なので、こう言うことも出来る。

$ cat hoge3.sh
#!/bin/bash
echo bash
perl -x $0
ruby -x $0

exit 0

#!/usr/bin/env perl
print("perl\n") ;

__END__

#!/usr/bin/env ruby
puts("ruby")

__END__
bashで実行
$ bash hoge3.sh
bash
perl
ruby
perlで実行
$ perl hoge3.sh
bash
perl
ruby
rubyで実行
$ ruby hoge3.sh
ruby

追記

って書いたけど、

改めて読みなおしたら、 ruby の場合 -x の存在意義って無いなあ?
何の為だろう、、、windows の為だろうか、、、

tsuiki.sh
#!/bin/bash
ruby -x $0
exit 0
#!/usr/bin/env ruby
puts("ruby")

^D            # コントロール + V、コントーロル + D で埋め込み(mac のターミナル)

puts("test")
$ bash tsuiki.sh
ruby
$ ruby tsuiki.sh
ruby

pythonの場合

python の場合は、-x があるものの、かなりの制限を掛けて、「一行のみ飛ばすだけですよーーー」と明記してある。

-x(原文)
Unix 以外の形式の #!cmd を使うために、ソースの最初の行をスキップします。これは、DOS専用のハックのみを目的としています。
(ドキュメントより引用)

とは言え、無理をすれば、

$ cat hoge4.sh
find . -type f | python -x  $0 ; exit 0
#!/usr/bin/env python
import sys
for line in sys.stdin:
   print(line.strip())
Aと同様の事
$ bash hoge4.sh
./bar
./foo
./hoge
.
.
.

みたいな事が出来なくもない。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2