トップページunix
1001コメント289KB

シェルスクリプト総合 その20

レス数が950を超えています。1000を超えると書き込みができなくなります。
0001名無しさん@お腹いっぱい。2012/06/08(金) 00:35:51.19
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。

□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashなので特に注意。
 FreeBSDユーザは/bin/shの正体がashなので注意。
 v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。
  http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/
  http://heirloom.sourceforge.net/sh.html
・csh/tcshのシェルスクリプトは推奨されません。
 (理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
 manや参考リンクを見ましょう。
 aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
 正規表現の話題はスレ違い(正規表現スレへ)

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。

前スレ
シェルスクリプト総合 その19
http://toro.2ch.net/test/read.cgi/unix/1323515200/
0858名無しさん@お腹いっぱい。2012/09/18(火) 15:12:12.83
ユーザーはソフトのインストール禁止ですが、
最近、ユーザーでも自分のホームフォルダーにソフトをコピーし、
X権限をすることによってソフトが実行できてしまうことが判明しました。
これはOSのセキュリティーボールではないのでしょうか?
ユーザーのフォルダーではたとえX権限がされていても
実行できないようなおすすめのシェルって何ですか?
必要ならカーネルにバッチを当てる方法も、やもうえません。
0859名無しさん@お腹いっぱい。2012/09/18(火) 15:15:18.02
コピペ改変
http://toro.2ch.net/test/read.cgi/unix/1000022300/775
0860名無しさん@お腹いっぱい。2012/09/18(火) 15:19:10.12
>>858
とりあえず /home以下をnoexecでmountしちゃえば?
0861名無しさん@お腹いっぱい。2012/09/18(火) 15:27:38.12
つまらんネタにかまうな。
0862名無しさん@お腹いっぱい。2012/09/18(火) 15:52:29.12
>>857
> するとフォーマットが合わないのでエラーで返ってくる。

これは先頭の2byteを見ていたのね。
そこから#!を使うことになった。comment(#) + execute(!)

昔の実行形式の先頭2byteがどういう値だったかは、
/usr/share/file/magic/pdpを見るといい。
古典的なUNIXでは/etc/magicにある。
典型的なテキストファイルでは使わないシーケンスになってる。
08638542012/09/18(火) 16:18:19.96
おまいら早いですねw (褒めてます)

>>857
> このあと、コマンドラインのシェルの判断で、
> 「sh ファイル名」の形に修正して再度カーネルのexec()を呼び直す。

ありがとうございます。この部分以外は自分の理解とおおむね一致していました。
自分の理解度を再確認できて良かったです。

ただ、「シェルの判断で〜」の部分ってシェルのマニュアルにはちゃんと書かれて
いるのか、それとも「昔からそういうもんだ。ソース読め」のどちらなんでしょう?

手元では tcsh / ksh / bash で同じ挙動だったので「昔からそういうもんだ」
なのかな、という予感です。
0864名無しさん@お腹いっぱい。2012/09/18(火) 16:23:15.64
マニュアルに書いてあるかどうかと昔からそういうもんかどうかって
択一じゃないと思う。
0865名無しさん@お腹いっぱい。2012/09/18(火) 16:34:37.60
shellがmagic numberを見て、shell scriptを自分で実行するようになったのは、
bash移行のことじゃないか? それまではexecve(2)におまかせだったはず。
0866名無しさん@お腹いっぱい。2012/09/18(火) 16:50:35.22
一応手持ちのGentooマシンで調べてみたけど
GNU bash 4.2.37ではまだexecveしてENOEXECが返されるのを確認してから
そのスクリプトを読み直して処理してるみたい。
0867名無しさん@お腹いっぱい。2012/09/18(火) 21:16:25.81
どーでもいいけど昔のHP-UXで一行目がシェバングじゃないコメント行だと
ログインシェルで解釈されたような気がする。
0868名無しさん@お腹いっぱい。2012/09/19(水) 11:56:29.71
#!/bin/cat
Hello,world!

って書いてもcatが起動しないんだけど、なんで?
0869名無しさん@お腹いっぱい。2012/09/19(水) 11:59:22.55
ごめん、起動してたわ
0870名無しさん@お腹いっぱい。2012/09/19(水) 12:06:17.94
cat -n で起動したらいろんな誤解が一瞬で解けた
0871名無しさん@お腹いっぱい。2012/09/19(水) 12:07:42.49
日記か。
0872名無しさん@お腹いっぱい。2012/09/19(水) 13:51:27.02
知識の共有だ
0873名無しさん@お腹いっぱい。2012/09/19(水) 20:18:30.82
A=`./hoge | cat`
みたいなとき、./hogeのエラーを検知してリトライしたいんだけど
どうしたらいいかな
0874名無しさん@お腹いっぱい。2012/09/19(水) 20:40:36.49
ためしてないけど
A=`while ! ./hoge; do :; done | cat`
ってかんじかなぁ
0875名無しさん@お腹いっぱい。2012/09/19(水) 20:54:25.77
>>874
そっかその中でループしちゃえばいいのか
0876名無しさん@お腹いっぱい。2012/09/22(土) 17:58:27.45
シェルの正しい文法って誰も知らないみたいなウィキペディアにはハッカー?さんのコメントがありますが
望ましいシェルスクリプトの実行方法は実行権付与後に当ファイルを呼び出す方式か、 shコマンドで引数にファイルパスを指定する方法か、 .コマンドで同様にパス指定する方法か、どれになりますでしょうかね
実行時の状況次第で選ぶものだとは思いますが。。
0877名無しさん@お腹いっぱい。2012/09/23(日) 05:23:02.47
文法がどう呼び出し方法の話とつながっているのかわからんが、
明らかに3つとも意図するところは違うだろ。
0878名無しさん@お腹いっぱい。2012/09/23(日) 23:34:02.91
というと?
0879名無しさん@お腹いっぱい。2012/09/24(月) 03:46:37.39
というと=tweet
0880名無しさん@お腹いっぱい。2012/09/24(月) 10:04:32.63
具体的に。
0881名無しさん@お腹いっぱい。2012/09/24(月) 10:59:38.29
誰か >>876 を3行で日本語にして
0882名無しさん@お腹いっぱい。2012/09/24(月) 11:08:32.60
(1) ./hoge.sh
(2) sh hoge.sh
(3) . hoge.sh
をどう使い分けるか。
0883名無しさん@お腹いっぱい。2012/09/24(月) 11:08:44.90
シェルスクリプトって実行権限与える、shに引数渡す、sourceで読み込むと、
三種類実行方法がありますが、それぞれどんな特徴ですか?
それはさておき、文法を完全に把握してる人がいないんですね。wikipediaに書いてありました。
0884名無しさん@お腹いっぱい。2012/09/24(月) 11:19:08.75
文法はさておきすぎとして、
(1)と(2)はそれほど明確に使い分けてないかもね
パーミッションが立ってることが保証できて、
普通のコマンドと区別する理由がなければ(1)
0885名無しさん@お腹いっぱい。2012/09/24(月) 11:23:20.30
コマンドラインから頻繁に実行するなら (1) にしたい。
ただ #! とかモードとかちゃんと設定しなければならない。
その辺がめんどうなら (2) で。
(3) は (1)(2) とは動きが違う。
0886名無しさん@お腹いっぱい。2012/09/24(月) 11:33:50.71
>>885
(3)が違うというのはなにが違うというのか
0887名無しさん@お腹いっぱい。2012/09/24(月) 11:35:36.73
>>886
子プロセスで実行するか現在のプロセスで実行するか。
0888名無しさん@お腹いっぱい。2012/09/24(月) 11:36:18.77
釣りくさいけど、変数に代入したりcdしたりして比べてみろ
0889名無しさん@お腹いっぱい。2012/09/24(月) 11:36:48.66
たとえば hoge.sh 内で cd / してみ。
0890名無しさん@お腹いっぱい。2012/09/24(月) 11:37:32.27
ダウンロードして一回だけ実行って時は、(2)をさせる記述が多いね。
0891名無しさん@お腹いっぱい。2012/09/24(月) 12:11:39.88
やっぱり文法の話が気になる。
0892名無しさん@お腹いっぱい。2012/09/24(月) 12:42:24.30
文法の話、参照先読んから書きたいんだけど、臨時串がNGワードではねやがる。

bash開発時にsh互換にするのに文法で苦労したんだって。
その時の語録みたいよ。
08938922012/09/24(月) 12:59:18.55
shのドキュメントがイマイチだったり、yaccが不完全だったんだって。
みんな使っている機能なのに。
だから「本当は誰もshの文法がどうなっているのか知らないんだよ。
ソースコードなんて読んだってほとんど役立たねえよ」ってことらしい。
0894名無しさん@お腹いっぱい。2012/09/24(月) 14:30:47.04
不完全って何だよ、もとからyaccなんか使ってねえよ
伝聞じゃなくてソース出せ
0895名無しさん@お腹いっぱい。2012/09/24(月) 14:45:31.61
http://ja.wikipedia.org/wiki/Bourne_shell#.E8.AA.9E.E9.8C.B2
コメントってこれのこと?
0896名無しさん@お腹いっぱい。2012/09/24(月) 14:46:52.91
http://www.linuxjournal.com/article/2800?page=0,2
yaccうんぬんはこれか。
0897名無しさん@お腹いっぱい。2012/09/24(月) 15:59:04.26
「yaccが不完全」とは書いてないな。
0898名無しさん@お腹いっぱい。2012/09/24(月) 16:08:48.36
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.41.3287&rep=rep1&type=pdf
コメントの出典。
0899名無しさん@お腹いっぱい。2012/09/24(月) 16:26:39.69
えwwwいwwwごwww
We are Japanese!
0900名無しさん@お腹いっぱい。2012/09/24(月) 16:54:24.62
rcの宣伝するのにshをdisってるだけで、bashだの互換性だの関係ないじゃん。
0901名無しさん@お腹いっぱい。2012/09/24(月) 16:56:23.03
>>900
>>892>>896を読んだんだろう。
0902名無しさん@お腹いっぱい。2012/09/24(月) 17:31:58.97
who|wcがだめなのって、昔のshはパイプが^だったっていうだけのこと?
0903名無しさん@お腹いっぱい。2012/09/24(月) 18:05:51.19
>>902
7th Edition なら「|」でいいっぽい。
http://plan9.bell-labs.com/7thEdMan/v7vol2a.pdf
0904名無しさん@お腹いっぱい。2012/09/24(月) 18:31:49.56
>>903
んっと、実質いけるかじゃなくて、ドキュメント上の話ね
0905名無しさん@お腹いっぱい。2012/09/24(月) 18:36:10.23
あぁ
>>903
は、1979のドキュメントか。who|sortがちゃんと例に上がってるね。
who|wcが認められていないっていう出典は何だ?
0906名無しさん@お腹いっぱい。2012/09/24(月) 19:15:26.74
こっちだと出典が載ってる。
http://tiswww.case.edu/php/chet/bash/article.pdf

出典はこれ。>>903に含まれてるのと同じっぽい。
http://www.alcatel-lucent.com/bstj/vol57-1978/articles/bstj57-6-1971.pdf

でもなんでダメなのかはよくわからん。
0907名無しさん@お腹いっぱい。2012/09/24(月) 20:02:57.99
bstjのは who|grep $1 みたいな例があるから出典としてはおかしいんじゃないかな。
Chet Rameyの出典ミスのような気がする。

とりあえず、open problemは、初出のTom Duffのrc文献で
> It is remarkable that in the four most recent editions of the UNIX
> system programmer's manual the Bourne shell grammar described in the
> manual page does not admit the command who|wc.
の根拠がわからない点かな。

なのにあちこち引用されてるという……
0908名無しさん@お腹いっぱい。2012/09/26(水) 20:55:09.39
そんなことよりshのソースを見て驚愕しようぜ。
0909名無しさん@お腹いっぱい。2012/09/26(水) 20:58:49.31
      /⊇∧
  /⊇∧〈( ゚д゚)
`〈( ゚д゚)ヽ ⊂ニ)
 ヽ_と/ ̄ ̄ ̄/ |
  ̄\/___/ ̄ ̄
0910名無しさん@お腹いっぱい。2012/09/27(木) 13:34:15.65
ウニ臭ってさ、コマンドライン画面にエロアニメ少女のAA出して
オナニーするんだろ?

本当にキモいよな。
0911名無しさん@お腹いっぱい。2012/09/27(木) 15:53:41.99
AA ってなんですか。
0912名無しさん@お腹いっぱい。2012/09/27(木) 16:49:20.71
>>911
http://ja.wikipedia.org/wiki/%E3%82%A2%E3%82%B9%E3%82%AD%E3%83%BC%E3%82%A2%E3%83%BC%E3%83%88
0913名無しさん@お腹いっぱい。2012/09/27(木) 22:53:41.05
マジレスってなんですか?
0914名無しさん@お腹いっぱい。2012/09/27(木) 23:37:10.23
>>913
http://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%B8%E3%83%AC%E3%82%B9
0915名無しさん@お腹いっぱい。2012/10/03(水) 23:49:51.10
わかる方いたら教えてください。
以下の@のようにコマンドを変数に代入して、実行したいのですが、どうすればよいですか。
多分、バックスラッシュが正しく認識されていない。。

@コマンドを変数に代入した場合はNG
cmd="find /tmp/ -name \*.tsv"
for f in `${cmd}`; do
echo ${f}
done

Aベタ書きするとOK
for f in `find /tmp/ -name \*.tsv`; do
echo ${f}
done
0916名無しさん@お腹いっぱい。2012/10/03(水) 23:54:39.82
for f in $(eval "$cmd");do
echo $f
done
0917名無しさん@お腹いっぱい。2012/10/04(木) 08:26:24.94
>>915
cmdに ' ' で代入すること " " だとバックスラッシュが解釈される。
0918名無しさん@お腹いっぱい。2012/10/08(月) 21:27:19.47
sed -e /1a porto=WPA/ wpa_supplicant.conf
で2行目にproto=WPAを挿入したしてますが、
タブ+proto=WPAを挿入するには、どうしたら出来ますか?


0919名無しさん@お腹いっぱい。2012/10/08(月) 21:38:16.14
>>918
sed -e '1a\\tporto=WPA' wpa_supplicant.conf
09209182012/10/08(月) 22:10:14.93
>919
あ、そうか
ありがとうございます。
0921名無しさん@お腹いっぱい。2012/10/09(火) 09:23:06.07
ある特定の命令を無視しろと命令したい場合どうすればいいの?
0922名無しさん@お腹いっぱい。2012/10/09(火) 09:57:32.69
命令ってなんのこと?
0923名無しさん@お腹いっぱい。2012/10/09(火) 10:01:49.88
あ、コマンドのこと。
0924名無しさん@お腹いっぱい。2012/10/09(火) 10:22:48.32
こういう事か? 突っ込みどころはいろいろあるがキミのレベルならこれで良い。

#!/bin/sh
ls () :
ls
0925名無しさん@お腹いっぱい。2012/10/09(火) 10:28:51.78
>>921
↓この人と一緒に考えるといい。
http://toro.2ch.net/test/read.cgi/tech/1348995216/574
0926名無しさん@お腹いっぱい。2012/10/10(水) 11:22:49.71
grepコマンドで、"---Hoge"という文字列を検索できません
どうしたらよいでしょうか
0927名無しさん@お腹いっぱい。2012/10/10(水) 11:26:04.61
まさか grep -- ---Hoge というオチじゃないだろな
0928名無しさん@お腹いっぱい。2012/10/10(水) 11:28:20.39
-- が使えないgrep用の解
grep '[-]--Hoge'
0929名無しさん@お腹いっぱい。2012/10/10(水) 11:30:08.66
grep -e --Hoge
0930名無しさん@お腹いっぱい。2012/10/10(水) 15:19:10.02
>>927-929
ありがとうございました
0931名無しさん@お腹いっぱい。2012/10/12(金) 19:22:12.36
すいません、教えてください。
at コマンドで、日付を指定することはできませんか?
4日後の午前8時に実行したいのです。
at コマンドじゃなくてもかまいません。
FreeBSD 4.7 です。
よろしくお願いします。
0932名無しさん@お腹いっぱい。2012/10/12(金) 19:35:22.65
なぜmanを読まない? 時刻と日数は違うけとそのものずばりが例にかかれてる。
0933名無しさん@お腹いっぱい。2012/10/12(金) 19:39:11.88
>>932
ありがとうございました。
8am + 4 days
で、いいんですね?
0934名無しさん@お腹いっぱい。2012/10/12(金) 20:09:51.12
>>933
日付は+1しないとダメだよ
0935名無しさん@お腹いっぱい。2012/10/23(火) 23:44:42.55
ネタ切れ
0936名無しさん@お腹いっぱい。2012/10/30(火) 14:47:21.49
すいません 教えてください。
あるMakefileの中に
変数:=XXXXX
変数+=XXXXX
の記述があるんですが、これってどう言う意味でしょうか
0937名無しさん@お腹いっぱい。2012/10/30(火) 14:57:50.73
マルチ乙
http://toro.2ch.net/test/read.cgi/unix/1079538957/
09389362012/10/30(火) 16:07:27.79
>937
だって、あちらは誰もいないみたいなんで
0939名無しさん@お腹いっぱい。2012/10/30(火) 19:36:36.28
それはスレ違いの書き込みしていい理由にはならない。
0940名無しさん@お腹いっぱい。2012/11/03(土) 22:03:05.39
makeのこときかれても.....
0941名無しさん@お腹いっぱい。2012/11/03(土) 22:57:10.70
だってワロタ
0942名無しさん@お腹いっぱい。2012/11/04(日) 10:42:30.42
chroot後に、プロンプトを変更しようとしています。
chroot /hoge export PS1="\u@\h \w->
プロンプト変更.shを作って
chroot /hoge /hoge/プロンプト変更.sh
としても、そのようなファイルやディレクトリはないと怒られます。
何故でしょうか?

0943名無しさん@お腹いっぱい。2012/11/04(日) 11:08:51.12
釣りか?
/hoge/プロンプト変更.sh は /hoge に chroot した後は /プロンプト変更.sh だろ。
0944名無しさん@お腹いっぱい。2012/11/04(日) 14:02:09.17
しかもプロンプト変更してすぐ終了するという意味不明な攻撃。
09459422012/11/04(日) 16:21:56.21
失礼しました。
プロンプト変更.shの中にエラーがありました
>942
どちらも試しておりましたが、スクリプトのエラーで分からなくなっていました。
おっしゃる通りですね
>944
こちらも試しては見ていたんですが
chroot ./hoge /bin/bash; /プロンプト変更.sh でしょうか
ただ、これもサブシェル内での変更になるのでしょうか、思うようにはなりませんでした。
chroot ./hoge /bin/bash; export PS1="->"
でもダメなので、bashrcを書き換えないとダメでしょうか?
0946名無しさん@お腹いっぱい。2012/11/04(日) 17:02:21.41
chroot云々は良く分からんが
. プロンプト変更.sh
source プロンプト変更.sh
じゃねーのか
0947名無しさん@お腹いっぱい。2012/11/04(日) 17:19:49.94
ツェル
0948名無しさん@お腹いっぱい。2012/11/04(日) 21:39:42.26
シェルの内部コマンドと外部コマンドの区別をつけないと。
0949名無しさん@お腹いっぱい。2012/11/05(月) 01:35:08.60
外部コマンドcdという一見不可思議なものもあったりするけどね。
0950名無しさん@お腹いっぱい。2012/11/05(月) 09:36:46.07
>>945
面倒だから正解教えてあげるけど、キミ、全然理解していない。
次に来るときはシェルの入門書を1000回読み返してからくるように。

chroot ./hoge /bin/bash --rcfile /プロンプト変更.sh
0951名無しさん@お腹いっぱい。2012/11/05(月) 11:07:47.92
>>949
そのディレクトリにcdが可能かどうかチェックはしたいけど
カレントディレクトリを変更したいわけじゃない、という場合に使う。
0952名無しさん@お腹いっぱい。2012/11/05(月) 11:10:09.44
>>951
それは (cd hoge) で十分。わざわざ/usr/bin/cd hogeとかする必要なし。
0953名無しさん@お腹いっぱい。2012/11/05(月) 11:51:33.94
/usr/bin/cd を使っちゃいけない理由もない。
0954名無しさん@お腹いっぱい。2012/11/05(月) 11:54:39.66
じゃあ外部コマンド版の以下のコマンドの意味のある用途は?

alias bg fg jobs unalias wait

もちろん、「文法チェック目的」以外で。
0955名無しさん@お腹いっぱい。2012/11/05(月) 11:56:21.15
>>953
/usr/bin/cd を使っちゃいけない理由:

/usr/bin/cdがインストールされていない環境で動かないのでポータビリティを損ねる。
0956名無しさん@お腹いっぱい。2012/11/05(月) 11:58:35.93
>>955
インストールされている環境でしか使わないスクリプトなら問題ない。
0957名無しさん@お腹いっぱい。2012/11/05(月) 12:18:17.16
>>954
POSIX Shell & Utilitiesに適合するため。
レス数が950を超えています。1000を超えると書き込みができなくなります。