トップページunix
987コメント278KB

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

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。2012/11/15(木) 18:57:33.11
シェルスクリプトの総合スレです。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashまたはdashなので特に注意。
 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でそれらしい単語による簡単な検索もできます。
・シェルで使えるワイルドカード等は正規表現ではありません。
 正規表現の話題はスレ違い(正規表現スレへ)
・シェルスクリプトのことをシェルってゆーな
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 awkまたはperlの方が適した処理にはそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
□回答者への注意事項:
・シェルスクリプトでの処理方法を質問しているのに、よくわからずに
 「そういうのはperl使いましょう」と回答するのはやめましょう。
 安易にperlに逃げずにシェルスクリプトで処理するのが頭のいいやり方。
前スレ
シェルスクリプト総合 その20
http://toro.2ch.net/test/read.cgi/unix/1339083351/
0545名無しさん@お腹いっぱい。2013/04/27(土) 01:31:18.66
''必要かな?
cat hoge.txt | sed
だとまずいsedってある?
0546名無しさん@お腹いっぱい。2013/04/27(土) 01:36:03.55
>>544
あ、cat でいいんですね、思いつかなかった・・・
ありがとうございました。

>>545
ほんとだ、'' は要らないですね。
0547名無しさん@お腹いっぱい。2013/04/27(土) 10:13:59.37
>>545
GNU sedは '' ないとマズ杉
0548名無しさん@お腹いっぱい。2013/04/28(日) 00:16:28.95
シェルスクリプトで、セキュリティ上パスに気をつけろという話がありますが、

1. コマンドを絶対パスで呼ぶ(/bin/ls とか)
2. PATHをスクリプトの冒頭で適切な値に再設定する

ですよね? でこれらに関して何ですが、とりあえず両方やった方がいいですかね?
あと、1. に関してはやはり test コマンドなんかも if /usr/bin/[ ... ] ; then ... fi って
やることになりますよね?

あと、1. で readonly LS=/bin/ls して ${LS} と呼ぶとしたら安全性は落ちますかね?
0549名無しさん@お腹いっぱい。2013/04/28(日) 00:24:04.62
少なくともbashの[ は組込み
0550名無しさん@お腹いっぱい。2013/04/28(日) 00:24:25.98
>>548
いったいどんな環境で使ってるの?
で、そこには悪意のあるユーザーがいて、悪意のあるプログラムに ls とか名前をつけてそこら中に散りばめられてる可能性があるの?
0551名無しさん@お腹いっぱい。2013/04/28(日) 00:44:59.50
/bin/lsがrmに置き換えられているかもしれないからハッシュ値を確認しないとな
0552名無しさん@お腹いっぱい。2013/04/28(日) 02:56:32.10
で、md5sum 自身も書き換えられてるとかw
0553名無しさん@お腹いっぱい。2013/04/28(日) 09:03:13.99
>>548 ですが、
とりあえず/binや/usr/binがあるパーティションは書き込み不能。
データ用の書き込み可能なパーティションが別にあります。
基本的にはログイン不能なシステムです。がネットワークのやり取りとか
はあるので何がどうなるかは...

システムのデーモンから呼ばれるスクリプトを作ろうとしていて、
一応、パスが改ざんされる可能性を考えています。
0554名無しさん@お腹いっぱい。2013/04/28(日) 09:10:39.10
どんなにスクリプトの書き方に注意しても人為的なミスは防げないんだし
その辺真面目にやるならAppArmorとかSELinuxとかその辺使った方がいいような希ガス
0555名無しさん@お腹いっぱい。2013/04/28(日) 09:20:46.40
>>553
>何がどうなるかは… (わからない)ようなシステムかよwww
パスが改ざんされるって、「誰」のパスが改ざんされるの?
そんなことする奴がいたらそもそもパスの改ざんだけですまんだろ?
0556名無しさん@お腹いっぱい。2013/04/28(日) 09:23:21.45
>>548
1.と2. 両方やった方がいい。

readonly PATH='' ってやって、PATHなしに強制する (''は書かなくても同じ意味)
これで、lsとか絶対パスでしか実行できなくなる。

testについては >>549 の指摘通り内部コマンドなので、
if [ ... ]; then って普通に書いていい。

readonly LS=/bin/ls はどっちでもいいかな。
見やすくなるかどうかくらいの意味なので。
0557名無しさん@お腹いっぱい。2013/04/28(日) 09:30:53.19
>>556
ダウト。
甘いな。
PATH='' だと、逆にカレントディレクトリ上のファイルが実行できる。
PATH=. と同じ状態。かえって危ない。

PATH=/dev/null がお勧め。
0558名無しさん@お腹いっぱい。2013/04/28(日) 09:44:14.51
あほばっかだな(笑)
PATHだけ取り上げて安全とか危ないとかwww
素直にセキュアOSの適用を考えろよ
0559名無しさん@お腹いっぱい。2013/04/28(日) 13:50:32.70
環境変数が改ざんされてたらエラー吐いて異常終了した方がよくね?
「パスが改ざんされてても正常終了します」とかゴミ仕様すぎる
0560名無しさん@お腹いっぱい。2013/04/28(日) 15:45:42.42
PATHが改ざんされてる(改ざんが疑われる)ような状況じゃ何やっても無駄だわw
好きなように書けw
0561名無しさん@お腹いっぱい。2013/04/28(日) 16:05:40.29
インフラをお客さんが握っている場合、自衛のために対策することがある
いちゃもんつけられても困るし
0562名無しさん@お腹いっぱい。2013/04/29(月) 02:37:46.66
質問です。

#! /bin/sh
run=:
msg="hanamogera"

case $1 in
--run)
run=
shift
"$@" && exit 0
if test $? -ne 0; then
run=:
echo "$msg"
fi
;;
esac
0563名無しさん@お腹いっぱい。2013/04/29(月) 02:38:51.05
って
bash-2.02$ ./hoge.sh --run ls -e
ls: illegal option -- e
usage: ls [-1ACFLRTWacdfikloqrstu] [file ...]
hanamogera
という実行結果なんですが、
なんで、
"$@" && exit 0
でシェルスクリプトが終了しないんですか?
0564名無しさん@お腹いっぱい。2013/04/29(月) 06:40:13.68
そりゃ ls -e が失敗したからだろ。
0565名無しさん@お腹いっぱい。2013/04/29(月) 07:19:07.54
>>563
C言語と同じで、&& はショートカット動作する。

A && B
は、Aが偽だった場合、Bを実行しない。
0566名無しさん@お腹いっぱい。2013/05/02(木) 11:31:15.22
exit値が、
0:成功
それ以外:失敗
を理解してないのかな?
&&は左辺が成功したら、右辺実行。
0567名無しさん@お腹いっぱい。2013/05/02(木) 13:57:32.04
>>566
0 が 真
ということに非常に戸惑いを覚える
0568名無しさん@お腹いっぱい。2013/05/02(木) 13:59:45.82
成功の理由を教えてもらう必要はないに等しいが、
失敗には必要だから-2,-1,1,2,3,4,...を使う。
0569名無しさん@お腹いっぱい。2013/05/02(木) 14:09:38.88
0 が 真 ということに非常に戸惑いを覚えた俺は、
想定した結果がでたら1、じゃなければ0、想定外なら0以外

とルールを作ってスクリプトを作った。

しかし他人のコマンドを混ぜると、0が真という糞プログラムばっかりで参ってる
0570名無しさん@お腹いっぱい。2013/05/02(木) 14:18:49.45
混ぜるなよw
0571名無しさん@お腹いっぱい。2013/05/02(木) 15:00:28.38
それじゃログインするなり周りは全部敵じゃないかw
0572名無しさん@お腹いっぱい。2013/05/02(木) 15:53:55.34
0が真 ってBASIC時代を思い出すよな
0573名無しさん@お腹いっぱい。2013/05/02(木) 16:17:55.23
CPUではZフラグが0のとき真(直前の演算結果が非ゼロだった)なんだよな
0574名無しさん@お腹いっぱい。2013/05/02(木) 16:32:12.60
>>567
0 が真ということに戸惑うって、そりゃ当たり前だろ。一般的に真偽値の 0 は FALSE であって、
それはすなわち偽を示すものだから。

シェルスクリプトにおける 0 は「成功」なのです。あなたの中では「真 == 成功」なのですか?
0575名無しさん@お腹いっぱい。2013/05/02(木) 17:05:11.27
>>574
君の中では「偽 == 成功」なのか?
0576名無しさん@お腹いっぱい。2013/05/02(木) 17:20:09.29
プロセスの終了コードが、エラーなしで終了したときは 0 になるのが普通だったので
シェルでは、コマンドの終了状態で判断する際に正常終了の 0 が、
論理値との対比では真に相当するのが都合がいいかな、
とボーン氏は考えたのだろう。
それ以前のシェルでも終了コードをチェックして云々はあったのかな?知らないんだけどね。
0577名無しさん@お腹いっぱい。2013/05/02(木) 17:44:27.92
エラーがFALSE(TRUEではない)なんだから、いいんじゃないの?
0578名無しさん@お腹いっぱい。2013/05/02(木) 18:15:32.05
算術IFなんかも整数使うけど、
真偽値とは別の概念として正、0、負を使い分けてる。
何の問題があるのでしょうか?
0579名無しさん@お腹いっぱい。2013/05/02(木) 18:26:12.54
別にいいけど自分が混乱するだろw
0580名無しさん@お腹いっぱい。2013/05/02(木) 18:26:57.74
別にいいけど自分が混乱するだろw
周りもだし。郷に入っては郷に従えだろ。
0581名無しさん@お腹いっぱい。2013/05/02(木) 18:27:40.13
大事なことだったのでつい。
0582名無しさん@お腹いっぱい。2013/05/02(木) 19:53:35.55
しょうがないにゃあ
0583名無しさん@お腹いっぱい。2013/05/02(木) 20:32:25.51
>>575
どっちでもないよ。「真偽」と「成功失敗」は異なる概念でしょ。
無理矢理当て嵌めようとするから、話が gdgd になってきてるんだと思う。
0584名無しさん@お腹いっぱい。2013/05/02(木) 21:25:27.24
windowsだと、関数の終了コードをbooleanにするのが普通になってしまっているので、その影響かもしれない。
0585名無しさん@お腹いっぱい。2013/05/02(木) 21:59:59.88
次に設計する偉い人は多値にしてくれ。
0586名無しさん@お腹いっぱい。2013/05/13(月) 19:10:08.38
>>575
数学的論理命題の話をしているのに、
逆が必ず真になるとの想定は如何なものか?
0587名無しさん@お腹いっぱい。2013/05/13(月) 19:20:16.84
シェル初心者だけど質問ある?
何でも聞け。
知らないこと以外はたいてい知っている。
0588名無しさん@お腹いっぱい。2013/05/14(火) 02:23:59.37
一休さん来た(棒読み
0589名無しさん@お腹いっぱい。2013/05/14(火) 22:53:01.49
>>587
シェルスクリプトでPASSを変える方法を教えてください。
0590名無しさん@お腹いっぱい。2013/05/15(水) 11:34:22.15
>>589
SET PASS=aaa
で環境変数PASSの変更が可能です
0591名無しさん@お腹いっぱい。2013/05/15(水) 14:28:33.17
シェルスクリプトでアブラムシの防除方法を教えてください。大変困っています。
0592名無しさん@お腹いっぱい。2013/05/15(水) 14:29:12.96
ネタ書き込む前にほんとにおもしろいか一度読み直してみような。
0593名無しさん@お腹いっぱい。2013/05/17(金) 01:39:50.41
シェルスクリプトでキー入力によって動作を変えたいのですが
readだとenterを押さないと入力された値を取得出来ません。

1.処理A
2.処理B
3.処理C
0.終了
実行する処理のキーを押してください>

上記のように画面上へ表示し、キーを押された時点で各処理実行したいのですが
シェルスクリプトで可能でしょうか?
0594名無しさん@お腹いっぱい。2013/05/17(金) 06:26:05.73
>>593
read -n 1
0595名無しさん@お腹いっぱい。2013/05/17(金) 07:17:32.96
>>594
read: 1: Illegal option -n
0596名無しさん@お腹いっぱい。2013/05/17(金) 07:19:27.17
>>593
key=`dd bs=1 count=1 2>/dev/null`
0597名無しさん@お腹いっぱい。2013/05/17(金) 07:26:23.44
>>596
stty cbreak 忘れてるぞ
事後に元に戻すのも忘れずにな。
0598名無しさん@お腹いっぱい。2013/05/17(金) 19:43:56.07
inkey$ を使えばいいニダ
0599名無しさん@お腹いっぱい。2013/05/17(金) 20:19:56.75
シェルじゃなくperlとかpythonとかのほうが楽?
0600名無しさん@お腹いっぱい。2013/05/17(金) 20:28:35.33
人によるんじゃない?
0601名無しさん@お腹いっぱい。2013/05/18(土) 01:17:39.94
perl も python も
インストールされていない
ということもあるw
0602名無しさん@お腹いっぱい。2013/05/18(土) 22:44:45.05
入力された拡張子を持つファイル一覧を出すスクリプトを作ろうと思ってるけどうまくいかない…
ボスケテ

#!/bin/sh
cd trash
extension=$@

ls | grep $extension

cd

extension経由させてんのはgrepだと正規表現とかが関係してうまくいかないんじゃないかと思ったから
助けてくれ…さっぱりわからないし調べても出てこない
0603名無しさん@お腹いっぱい。2013/05/18(土) 23:26:55.16
>>602
何がうまく行ってないのか説明してくれないと分からん。
0604名無しさん@お腹いっぱい。2013/05/18(土) 23:38:08.84
これを例えばtxtもつ奴だけ並べようとして実行すると(ファイル名challe5)
./challe5.sh* txt
grep: txt をオープンできません。
と出てそこで終了してしまう
どうすればいいんだ
0605名無しさん@お腹いっぱい。2013/05/19(日) 00:45:21.09
>>604
./challe5.sh* txt
の * は何のため?
ひょっとして、次のように * の前後に空白が這いよってない。
./challe5.sh * txt
0606名無しさん@お腹いっぱい。2013/05/19(日) 01:11:17.99
>>605
できた!
./challe5.sh txt で正しく動いた
ありがとう
0607名無しさん@お腹いっぱい。2013/05/19(日) 09:22:36.36
もしかして、 ls が ls -F に alias されていて、
実行可能ファイル名に末尾に * がついてたのを
勘違いしたんだろうか。
0608名無しさん@お腹いっぱい。2013/05/19(日) 12:09:10.88
解決まで読んでも何がしたいのか、さっぱりわからんw

ls ./trash/*.txt
で済んでしまいそうな。
あと多分cd -の方がいい。
0609名無しさん@お腹いっぱい。2013/05/20(月) 11:46:33.00
スクリプトに引数渡す練習かな。
最後に cd する理由はよくわからん。cd - に変える必要もないっしょ。
0610名無しさん@お腹いっぱい。2013/05/20(月) 14:29:43.96
元のデレクトリに戻したいだけだろ
そもそもcd trashが不要だろというのはおいといて
0611名無しさん@お腹いっぱい。2013/05/20(月) 14:53:12.21
元のディレクトリに戻ったところで
スクリプトの実行終わったら関係ないよね。
0612名無しさん@お腹いっぱい。2013/05/20(月) 15:00:49.43
わからねえならいいや
俺には関係ねえし
0613名無しさん@お腹いっぱい。2013/05/20(月) 15:38:14.12
>>612
オレもマジで分からんが。
スクリプト内の最終行で、元のディレクトリに戻らなければならない事例を挙げてくれよ
0614名無しさん@お腹いっぱい。2013/05/20(月) 16:15:55.91
気分がいいんじゃないか?
0615名無しさん@お腹いっぱい。2013/05/20(月) 17:03:05.27
何かやってて何か調べてwdに戻りたいつーだけだろ
わからねえならいいつってんのも読めないのかよ知障
0616名無しさん@お腹いっぱい。2013/05/20(月) 19:21:55.30
>>615
君がよくても、我々がよくない。
開き直って逆ギレしないで、
我々の知的好奇心を満たすために協力したまえ
0617名無しさん@お腹いっぱい。2013/05/20(月) 19:41:21.85
>>613
次に実行するスクリプトのためだろ

そういうコード書くな、で済むならいいけど
現実そういうわけにもいかないし
それなら毎度立つ鳥跡を濁さない方がいい
0618名無しさん@お腹いっぱい。2013/05/20(月) 20:24:44.35
>>617
最後に元のディレクトリに戻っても戻らなくても
次に実行するスクリプトには関係なくね?
0619名無しさん@お腹いっぱい。2013/05/20(月) 20:30:45.71
source や . で呼ばれるときに備えて元のディレクトリに戻っておくのはあるかもね。
>>602 がそこまで考えてるかどうか分からんけど。
0620名無しさん@お腹いっぱい。2013/05/20(月) 20:46:26.14
そんな呼び方するかねぇ。
0621名無しさん@お腹いっぱい。2013/05/20(月) 21:25:45.61
>>620
されたときのことを考慮するんだよ
0622名無しさん@お腹いっぱい。2013/05/20(月) 21:49:57.22
無引数cdした方がいいかどうかわからんだろ。
sourceされた時のことを考えて、(cd ...; xxx)ならまだわかるが。
06236022013/05/20(月) 21:51:17.99
最後のcdは元の場所に戻っておきたいなーと思って入れといた
ls ./trash/*txt は単に思いつかなかったw
>>607はたぶん大当たり
ガッコの課題でそういうシェルプログラム組めって言われたからつい大仰なのを作ってしまった
物議を醸してすまなかったぜ
0624名無しさん@お腹いっぱい。2013/05/20(月) 21:52:31.15
ちなみにcdだけでホームディレクトリ(でいいのか?)に戻るようになってる
(普通もそうなってるかはわからんので補足)
0625名無しさん@お腹いっぱい。2013/05/20(月) 21:54:30.64
学校の課題なのは薄々気付いてたけど
そんなに大仰でもないような。
0626名無しさん@お腹いっぱい。2013/05/20(月) 21:56:34.48
俺にとっては大仰なんだよ!
0627名無しさん@お腹いっぱい。2013/05/20(月) 22:24:58.07
>>623
なんで戻っておきたいの?
0628名無しさん@お腹いっぱい。2013/05/20(月) 22:46:30.24
>>623
> 最後のcdは元の場所に戻っておきたい
それなら、>>608の指摘通り「cd -」とすべきだな。
cdだと、元の場所ではなくて$HOMEに移動してしまう。
元の場所が$HOMEなら、同じだけど。

>>618
おぉ、sourceや . で呼び出すときの挙動をよく考えたことがなかったので、
ちょっと実験してみよう。
0629名無しさん@お腹いっぱい。2013/05/20(月) 22:46:37.20
はっきりいって特に戻っておきたい、と思った明確な理由はない
ただなんとなくつけただけだ
その上で、強いて理由を挙げるのであれば、ホームディレクトリでこのプログラムを起動した後
一回trashに言ったままになっちゃうのが面倒と思ったから

察して試してみたが別にcd無くても勝手に元に戻るみたいね…
0630名無しさん@お腹いっぱい。2013/05/20(月) 22:48:00.34
もちろんもとの場所も$HOMEです(おそらく)
0631>>6022013/05/20(月) 22:49:16.68
>>629-630は俺です
お目汚し失礼しました
0632名無しさん@お腹いっぱい。2013/05/20(月) 23:01:09.18
>>629
> 察して試してみたが別にcd無くても勝手に元に戻るみたいね…
「戻る」っていうか、
そのプロセスのカレントディレクトリは変わってないんだよ。
スクリプトとして呼ばれた子プロセスのカレントディレクトリが変わってるだけで。
0633名無しさん@お腹いっぱい。2013/05/20(月) 23:01:58.11
>>629
仮に「戻る」としても、
ホームディレクトリ以外にいるときに実行することは考えないのか?
0634名無しさん@お腹いっぱい。2013/05/20(月) 23:07:47.22
>>632 なるほど
>>633 それは確かに考えるべきだったな
書いたときは全然考えなかったわ(授業でやってる事は今のところ全部ホームディレクトリでやってるから)
まあ、初心者故に考えなかった、ってことだな
0635>>6022013/05/20(月) 23:08:44.03
>>634も俺
0636名無しさん@お腹いっぱい。2013/05/21(火) 00:30:10.63
ここは、書いたシェルスクリプトの投稿とかありか?
評価してほしいんだが
0637名無しさん@お腹いっぱい。2013/05/21(火) 00:50:08.35
やっぱいいや
0638名無しさん@お腹いっぱい。2013/05/21(火) 01:02:43.56
ありだよ。
0639名無しさん@お腹いっぱい。2013/05/21(火) 01:53:42.08
#!/bin/sh
while true
do
echo 'SEX shitai'
done
0640名無しさん@お腹いっぱい。2013/05/21(火) 02:07:26.42
echo oremo shitai
0641名無しさん@お腹いっぱい。2013/05/21(火) 07:29:23.70
シェルの手動起動の課題をやってます。
メモ帳でテキストファイルにEcho Helloとだけ書いて
サンバでH:ドライブに test.sh という名前を付けて保存、
TeraTermでtest命令を発行してもうまくシェルが動きません。
何かヒントください。
0642名無しさん@お腹いっぱい。2013/05/21(火) 07:44:12.55
その質問の仕方では答えられません
何かヒントを下さい
0643名無しさん@お腹いっぱい。2013/05/21(火) 09:37:22.82
>>642
w

>>641
sambaとかTeraTermとかいうからWindows環境だと思うが、
Windows以外の世界は、case sensitiveだということを覚えておこう
0644名無しさん@お腹いっぱい。2013/05/21(火) 09:40:26.49
実行後にカレントディレクトリが変更されるスクリプト
ってどうやって書けばいいの?
■ このスレッドは過去ログ倉庫に格納されています