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

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

■ このスレッドは過去ログ倉庫に格納されています
0001シェルスクリプトライター2011/12/10(土) 20:06:40.38
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。

□お約束
・特記なき場合は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 でトレースしましょう。

前スレ
シェルスクリプト総合 その18
http://hibari.2ch.net/test/read.cgi/unix/1308195527/

次スレは >>970 で。
0252名無しさん@お腹いっぱい。2012/01/30(月) 21:24:08.05
>>251
なるほど、そういうテクニックがあるんですね。
勉強になりました。
どうもありがとうございました。
0253名無しさん@お腹いっぱい。2012/01/31(火) 01:12:06.63
>>251
流石に「どのOSでも」は言い過ぎではw
まあsh動く環境ならまず大丈夫だとは思うから実害はないが
0254名無しさん@お腹いっぱい。2012/01/31(火) 06:11:03.04
>>253
いいや、「どのOSでも」OK。

反論するなら反例を挙げろや、カス。
0255名無しさん@お腹いっぱい。2012/01/31(火) 08:01:25.65
縛りはOSだけでいいの?
じゃ MS-DOS を挙げよう。
UNIX系OS特有なんだし、少なくともPOSIXに準拠してなきゃ持ってないよ。
0256名無しさん@お腹いっぱい。2012/01/31(火) 08:27:24.42
>>255
お前ほんとにアホだなw
MS-DOS ではシェル(スクリプト)は使えない。
0257名無しさん@お腹いっぱい。2012/01/31(火) 08:32:02.94
>>253
もとの質問の >>249 read -s -n 1 < /dev/tty の readの -s -n オプションは
bash依存だが、/dev/ttyがOS依存なんて話は聞いたことがない。

テストスクリプトとして
----
#!/bin/sh
echo hoge > /dev/tty
----
があるとして、このスクリプトが「/dev/tty」が無いのが原因で動かないようなOSを
挙げてくれるかな。>>253 よ。まあ、無理だろうけどw
0258名無しさん@お腹いっぱい。2012/01/31(火) 08:36:03.03
>>255
>POSIXに準拠してなきゃ持ってないよ

/dev/ttyはPOSIX以前からあるよ
0259名無しさん@お腹いっぱい。2012/01/31(火) 08:48:05.58
>>256-258
もうほっとけ。
質問者の質問に自分では答えずに、
正しく回答した回答者に後から間違ったつっこみを入れる >>253 のようなアホは
いつの時代にも居るから。
0260名無しさん@お腹いっぱい。2012/01/31(火) 09:28:37.54
FreeBSDでは/dev/ttyに直接アクセスしようとするまで存在しないのか。
0261名無しさん@お腹いっぱい。2012/01/31(火) 09:39:19.39
アスペだらけのスレで「posixな」とか「シェルスクリプトが動く」などの制約を付けずに
> /dev/ttyはどのOSでも移植性がある。
と言っちゃった>>253の負け。
0262名無しさん@お腹いっぱい。2012/01/31(火) 10:03:34.61
確かにそこだけ切り取ればWindowsも無いわな
0263名無しさん@お腹いっぱい。2012/01/31(火) 10:05:33.60
負けは>>253じゃなくて>>251だった。
0264名無しさん@お腹いっぱい。2012/01/31(火) 10:09:49.20
>>255
MS-DOS版の sh.exeでは /dev/tty動くぞ。sh.exe内部で解釈してるらしい。
0265名無しさん@お腹いっぱい。2012/01/31(火) 12:57:13.51
http://cl.ly/1z1S0Y2g3n0L133x0X2M

写真の同じやつ整理したくてこんなん書いたんだけど,
いかんせん遅い・・・
どうやったらもうちょっと早くなるかな?
0266名無しさん@お腹いっぱい。2012/01/31(火) 13:33:07.43
>>265
遅い原因は毎回md5sumを呼んでいるから
md5sum "$@"で求めておいて、その結果に対しての処理ならそれほど遅くない
アルゴリズムもcut -d' ' -f1してsortしてuniq -dして重複ファイルのMD5だけ列挙
そのMD5でgrepすればファイル名も分かるだろ
0267名無しさん@お腹いっぱい。2012/01/31(火) 13:39:35.46
一気にmd5取る、md5でソート、ユニークなものだけ移動。残りは重複したファイル。

ユニークなファイルのリスト
md5sum "$@" |sort -k 1 | uniq -w 32 |cut -d' ' -f 2
0268名無しさん@お腹いっぱい。2012/01/31(火) 13:39:36.12
rsyncを--dry-runで走らせるくらいで十分、かつ速いんじゃないかと
何の検証もせず言ってみる
0269名無しさん@お腹いっぱい。2012/01/31(火) 16:00:18.26
>>266-267
md5sumコマンド起動のオーバーヘッドより、
MD5計算時間の方がはるかに長いから、
毎回md5sumを呼んでも、ファイル名引数まとめてmd5sumを呼んでも
ほとんど改善しないよw

それより、まずはファイルサイズだけ見て、
同じファイルサイズのファイルが他にない場合は無条件でユニークなファイルとして
md5sum計算対象から除外した方がよい。
0270名無しさん@お腹いっぱい。2012/01/31(火) 16:06:28.42
写真ファイルの同一検出ならファイル全体のmd5計算しなくても、
適当な位置で4KBくらい抜き出すのでもよさそうな
0271名無しさん@お腹いっぱい。2012/01/31(火) 17:27:47.76
>>269
そんなところで高速化図ったんじゃねーよ。
見当はずれの言いがかり付けるって惨めだぞ。w
0272名無しさん@お腹いっぱい。2012/01/31(火) 17:43:31.60
>>269
ソース読んでないだろwどのみちMac何だからそういう機能持ったアプリありそうだと思う。それ使った方がいい
0273名無しさん@お腹いっぱい。2012/01/31(火) 18:01:40.88
読んだけどわからなかっただけだろ。
0274名無しさん@お腹いっぱい。2012/01/31(火) 19:11:12.35
openって何だろうと思ったらMacにはそういうコマンドがあるのか。
0275名無しさん@お腹いっぱい。2012/01/31(火) 19:29:02.96
で、openってなに?
0276名無しさん@お腹いっぱい。2012/01/31(火) 20:30:08.94
$ open foo.txt
$ open -a /Application/TextEdit.app foo.txt
$ open -a /Application/Emacs.app/Contents/MacOS/Emacs foo.txt
こんなコマンド。
0277名無しさん@お腹いっぱい。2012/01/31(火) 21:06:38.95
適当なアプリ探して、バックグラウンドでそいつを渡すわけね
0278名無しさん@お腹いっぱい。2012/01/31(火) 21:16:36.01
openはNEXTSTEP由来でファイルやディレクトリを開くコマンド
0279名無しさん@お腹いっぱい。2012/02/01(水) 11:43:16.32
OSXのopenコマンドは
open .
でカレントディレクトリをGUIで開かせるってのが一番使うかな
0280名無しさん@お腹いっぱい。2012/02/01(水) 12:05:32.98
blogに書いてろ
0281名無しさん@お腹いっぱい。2012/02/01(水) 12:58:13.47
>>269は理解できたのかな? w
0282名無しさん@お腹いっぱい。2012/02/01(水) 16:07:29.43
md5 でなんとかなる程度なら
さいしょから samefile なり samesame でよいのでは
02832652012/02/01(水) 17:06:16.13
http://cl.ly/221Q2p202r1f0g232K1Q

みんなありがとう!
こうかな?
02842652012/02/01(水) 17:09:15.95
あ,最初で移動してたら次のmd5sumの$@がないて言われるね\(^o^)/
0285名無しさん@お腹いっぱい。2012/02/01(水) 18:13:12.63
>>283
>>269は全然わかってないマヌケな素人だから、奴の指摘は全部無視していい。
サイズなんて調べる必要ない。
0286名無しさん@お腹いっぱい。2012/02/01(水) 23:15:24.01
testコマンドで質問です。
man testを見てみると、以下の2つのオプションの説明があります。

1.-nオプションのところ
True if the length of string is nonzero.

2.stringオプションのところ
True if string is not the null string.

これらの違いは、何があるのでしょうか?それとも同じなのでしょうか?
出来ればサンプルスクリプトで説明していただけると助かります。


0287名無しさん@お腹いっぱい。2012/02/02(木) 00:06:01.32
stringオプション?
0288名無しさん@お腹いっぱい。2012/02/02(木) 00:19:26.32
>>286
直接引用しろ。うちでは等価って書いてある
0289名無しさん@お腹いっぱい。2012/02/02(木) 01:32:54.28
シェルスクリプトの勉強をしたいのですが、
何シェルがいいですか。
0290名無しさん@お腹いっぱい。2012/02/02(木) 01:40:36.62
これの事だな。
http://www.freebsd.org/cgi/man.cgi?query=test&apropos=0&sektion=0&manpath=FreeBSD+9.0-RELEASE&arch=default&format=html

-n string True if the length of string is nonzero.
string True if string is not the null string.

違い
test -n $nonexistent; $? <= バグ? test -z $nonexistent; $?と矛盾する
test $nonexistent; $?
0291名無しさん@お腹いっぱい。2012/02/02(木) 03:44:03.15
>>289
>>1
特記ない限り bourne shell ということは、それを選択すれば無難ということ。
Linux オンリーなら bash だろうけど。
0292名無しさん@お腹いっぱい。2012/02/02(木) 06:26:43.33
>>289
そんな貴方に、Windows Power Shell。
0293名無しさん@お腹いっぱい。2012/02/02(木) 08:40:58.52
>>290
なんだよ、矛盾するって。
0294名無しさん@お腹いっぱい。2012/02/02(木) 08:59:55.63
自分が何調べてるかを理解してないだけに見える
0295名無しさん@お腹いっぱい。2012/02/02(木) 09:17:20.91
オペレータだけ与えるとstringと解釈するのか。エラーにしろよお。
0296 忍法帖【Lv=4,xxxP】 2012/02/02(木) 23:56:58.70
>>292
なんかUNIXのシェルより強力って書いてあるのが多いけどマジ?
0297名無しさん@お腹いっぱい。2012/02/03(金) 10:31:06.58
「協力」の基準をどう考えるか次第でどうとでも
0298名無しさん@お腹いっぱい。2012/02/03(金) 20:58:42.50
いま流行のステマとか
0299名無しさん@お腹いっぱい。2012/02/04(土) 08:30:04.97
>>296
シェルそのものの機能は確かに強力だけど
肝心のコマンド資産がなさ過ぎて実用シェルとしてはなあ…
0300名無しさん@お腹いっぱい。2012/02/04(土) 08:42:10.79
パワシェルはインタラクティブに使うとしょぼい。
03012652012/02/04(土) 22:16:58.57
>>284
最終的にこれで出来ました!
みなさんありがとうお(^ω^)

http://cl.ly/152U342e2o212b2B1q3j
0302名無しさん@お腹いっぱい。2012/02/09(木) 07:27:17.71
遅レスだけど、PowerShellは.Netのライブラリも呼べるしWin32APIも呼べるから、Windowsのシェルとしては強力だわ

それを参考にシステムコールや動的ライブラリをロード・実行する機能を持ったシェルが作られたとしても
自分はあんまり使いたいと思わんな。そういう機能の需要と言うか必要性はあるのかどうか
0303名無しさん@お腹いっぱい。2012/02/09(木) 14:49:30.97
PowerShellはいい加減スレ違いな気がするけれども……
その手の機能が欲しいときはぶっちゃけLL使えばよくね、と俺は思ってしまう

それよりもシェルとしては以下の点がネックで、cmd.exeに比べてすら劣る
・デフォルトでスクリプトの実行が禁止されているので配布物でのスクリプト利用は
 事実上不可能
・入力リダイレクトが使えない
・オブジェクトパイプラインという一見高機能なものを備えているが、代償として
 バイナリデータをパイプやリダイレクトで扱えない

最後の問題が困る。外部コマンドをパイプでチェインする場合もPowerShellが
間に割って入って無駄にテキストに変換するので、データを壊すだけでなく
多分無駄に非効率でもある

XPではそれに加えて我慢がならないほど起動が遅かった(ngen使っても)ので
遊んでみようという気にすらならなかったけど
Windows7では起動時間は我慢できる範疇になったな
0304名無しさん@お腹いっぱい。2012/02/09(木) 16:28:39.02
>PowerShellはいい加減スレ違いな気がするけれども……

だったらgdgd書かなきゃいい
0305 忍法帖【Lv=3,xxxP】 2012/02/09(木) 16:51:38.01
>>303
>・デフォルトでスクリプトの実行が禁止されているので配布物でのスクリプト利用は
> 事実上不可能
うんこやん
0306名無しさん@お腹いっぱい。2012/02/09(木) 22:51:58.68
質問です。

$ cat hoge
$GLOBALS['hoge']['huga']
$GLOBALShogehuga
とします。

$ grep $GLOBALS\[\'hoge\'\]\[\'huga\'\] hoge
とすると、どちらの行も引っかかってしまいます。

$GLOBALS['hoge']['huga']
だけ引っかけたいのですが、どうすればよいでしょうか、ご教示ください。
0307名無しさん@お腹いっぱい。2012/02/09(木) 23:03:56.62
$ grep "\$GLOBALS\['hoge'\]\['huga'\]" hoge
0308名無しさん@お腹いっぱい。2012/02/09(木) 23:05:25.02
grepに食わせるべきパターンが $ [ ] をエスケープした
¥$GLOBALS¥['hoge'¥]¥['huga'¥]
なので、これをシェル的にクォートする必要がある。

シングルクォートでがんばるなら
'¥$GLOBALS¥['¥''hoge'¥''¥]¥['¥''huga'¥''¥]'

正規表現として解釈されることを意図していないならfgrep使えば?
とか思ったりもする。
0309名無しさん@お腹いっぱい。2012/02/09(木) 23:42:52.43
>>306
$ grep -F "\$GLOBALS['hoge']['huga']" hoge
0310名無しさん@お腹いっぱい。2012/02/10(金) 08:45:25.71
>303
すれ違いかもしれんが参考になった
(unix shell 人視点の評価として)
0311名無しさん@お腹いっぱい。2012/02/10(金) 12:45:56.45
>>310
すれ違いかもしれんが

> (unix shell 人視点の評価として)

こゆとき俺はこーかく

( unix shell 人視点の評価として )
0312名無しさん@お腹いっぱい。2012/02/10(金) 13:15:55.88
>>311
そう書くとunixから定義しないといけない
0313名無しさん@お腹いっぱい。2012/02/10(金) 13:41:46.96
ここはunix shell人のいるスレですね。
0314名無しさん@お腹いっぱい。2012/02/10(金) 13:46:55.14
()は空白開けなくても大丈夫だろ。{}は必要だけど。
0315名無しさん@お腹いっぱい。2012/02/10(金) 13:47:22.31
>>307-309
grep の件、man もロクに読まない私にお力添えいただき、ありがとうございました。
m(__)m
0316名無しさん@お腹いっぱい。2012/02/13(月) 21:53:21.26
質問です。

あるスクリプトをホームディレクトリに作ったのですが、以下の条件があります。
・他の人もそのスクリプトを実行できるようにしたい
・でもファイルの中身は他の人は見れないようにしたい。

このような場合、一般的にはどのような手法がとられるのでしょうか?
0317名無しさん@お腹いっぱい。2012/02/13(月) 22:07:38.54
そういう無茶なことは考えない方がいい。
0318名無しさん@お腹いっぱい。2012/02/13(月) 22:09:09.60
(chmod 0711じゃ)いかんのか?
0319名無しさん@お腹いっぱい。2012/02/13(月) 22:20:32.11
うちにあるsudoのパーミッションが -r-s--x--x で、実際実行はできるけど
中身はみられない。適当なシェルスクリプトを作って同じパーミッションにして
みたけど、実行したらPermission deniedsetuidになってしまった。 (OSXにて)
0320名無しさん@お腹いっぱい。2012/02/13(月) 22:21:22.41
setuidというフレーズを消しわすれてしまった。

0321名無しさん@お腹いっぱい。2012/02/14(火) 00:05:14.25
スクリプトはインタープリターに読んでもらわないと実行できない。
そして、インタープリターは実行する人の権限で動作する。
したがって、スクリプトは実行する人が読むことができる。できなければ実行できない。
0322名無しさん@お腹いっぱい。2012/02/14(火) 00:21:01.04
つBATCOM
0323名無しさん@お腹いっぱい。2012/02/14(火) 01:25:34.75
なるほどぉー
0324名無しさん@お腹いっぱい。2012/02/14(火) 06:10:33.21
じゃあコンパイルできる言語で書き直すとか
0325名無しさん@お腹いっぱい。2012/02/14(火) 06:50:57.33
UNIXサーバーの管理をしています。
ユーザーはスクリプトの実行は禁止ですが、
最近、ユーザーでも自分のホームフォルダーにスクリプトをコピーし、
X権限をすることによってスクリプトが実行できてしまうことが判明しました。
これはOSのセキュリティーボールではないのでしょうか?
ユーザーのフォルダーではたとえX権限がされていても
実行できないようにする方法はありますか?
必要ならカーネルにバッチを当てる方法も、やもうえません。
0326名無しさん@お腹いっぱい。2012/02/14(火) 08:28:25.69
>>325
> ユーザーはスクリプトの実行は禁止ですが、
なんか御幣のある言い方をしているようにも思えるが、つまりのところ特定コマンド
以外は実行させたくないんだろ?
であればログインスクリプトを制限がきつい奴にすれば出来る。
bash の rbash の項目の man page かググって調べろ。
.bashrc や .bash_profile などを個人で書き換えられないようにしておかないと意味が無かったりと
環境整備には手間がかかるとは思うが。

> ユーザーのフォルダーではたとえX権限がされていても
> 実行できないようにする方法はありますか?

以下を実行して↑に何の意味も無いことを学べ。
chmod 644 sample.sh
/bin/sh ./sample.sh

これ以上はスレチなのでここでの質問をクローズした上で、以上の情報を元に自分で調べるか
適切なスレに行って再質問されたし。
0327名無しさん@お腹いっぱい。2012/02/14(火) 08:30:28.16
ネタだろ。
かまっちゃいかんよ。
0328名無しさん@お腹いっぱい。2012/02/14(火) 08:34:56.59
ここからのコピペ
http://toro.2ch.net/test/read.cgi/unix/1000022300/775-
0329名無しさん@お腹いっぱい。2012/02/16(木) 01:53:58.03
mountにnoexecってなかったっけ?nodevはあったよな。
0330名無しさん@お腹いっぱい。2012/02/16(木) 02:11:23.48
コンパイルできるシェルはありませんか?
0331名無しさん@お腹いっぱい。2012/02/16(木) 03:11:31.80
つ ttp://ftpmirror.gnu.org/bash/
0332名無しさん@お腹いっぱい。2012/02/16(木) 15:25:59.88
だから、コンパイルできるシェルはありませんか?
0333名無しさん@お腹いっぱい。2012/02/16(木) 15:26:22.53
ありません。
0334名無しさん@お腹いっぱい。2012/02/16(木) 15:38:01.31
>>330
int main(){return system("シェルスクリプト本文");}

って書けばコンパイルできるよ。
C言語上での文字列改行を行なえば複数行も記述できる。
0335名無しさん@お腹いっぱい。2012/02/16(木) 19:45:29.07
shcの事か?
0336名無しさん@お腹いっぱい。2012/02/19(日) 20:05:22.42
初心者なんですけど、16進数のテキストデータをシェルスクリプトでバイナリ化する事はできますかね?
0337名無しさん@お腹いっぱい。2012/02/19(日) 20:23:44.75
printf '¥x68¥x6f¥x67¥x65?n'
0338名無しさん@お腹いっぱい。2012/02/19(日) 21:15:12.00
>>337
これがヒントなんですか??
全然理解できへん(~_~;)
0339名無しさん@お腹いっぱい。2012/02/19(日) 21:46:07.41
echo 686f 6765 0a | xxd -r -p
0340名無しさん@お腹いっぱい。2012/02/20(月) 02:10:00.67
/etc/rcファイルを読んでるんですけど、
全く理解できません。
しょっぱなにこれが有るんですが、
stty status '^T'
なんのためにあるのでしょうか?
rcファイルが読まれ始めるときは、^Cや^Hが設定されていないという事?
ですか?
さらに、
if [ -f /etc/rc.first ]
then
. /etc/rc.first
fi
という一文は
/etc/rc.firstが存在するならば、/etc/rc.firstを実行するという意味だと思うんですが、
-fオプションはググると
「file が普通のファイルならば真となる。」
とありましたが、普通ではないファイルって有るんでしょうか?
0341名無しさん@お腹いっぱい。2012/02/20(月) 06:22:24.92
普通ファイルをそういう意味で捕らえるのはフレッシュ過ぎて噴いたw懐かしさがこみ上げてくるレベル
0342名無しさん@お腹いっぱい。2012/02/20(月) 07:02:39.19
CP/Mあたりだと、普通ではないファイルを使った階層化ができなかったなw
0343名無しさん@お腹いっぱい。2012/02/20(月) 09:07:07.89
>>340
UNIXではデータを書いたり読んだりするいわゆるファイルの他にも
OSが管理している資源やその他の物に名前をつけてファイルとして
扱うことができる。

デバイスファイルやディレクトリ、ソケット、シンボリックリンク、その他。
0344名無しさん@お腹いっぱい。2012/02/20(月) 19:39:24.99
「普通のファイル」って訳は最近では一般的なのかね?
「レギュラーファイル」でいいんじゃないかと思うが。
0345名無しさん@お腹いっぱい。2012/02/20(月) 19:41:36.51
>>336
「16進数のテキストデータ」はどこにあって、どういう形式なのか?

「バイナリ化」するとは具体的にどういうことか?
元の「16進数のテキストデータ」はバイナリではないのか?
Unicode文字のエスケープ表現か何かなのか?
0346名無しさん@お腹いっぱい。2012/02/20(月) 20:17:11.46
>>344
regular fileに対する確立された訳語は「通常ファイル」じゃないか。
0347名無しさん@お腹いっぱい。2012/02/20(月) 20:39:01.78
test -f FILE

「FILEが通常、ファイルなら真になる」

通常はファイルならば真なんですね。通常じゃない時は真にならないんですか?
0348名無しさん@お腹いっぱい。2012/02/20(月) 21:50:38.98
ディレクトリにテストしてみれば一発やん。

test -f /etc/passwd && echo file || echo 'not file'
test -f /etc && echo file || echo 'not file'
0349名無しさん@お腹いっぱい。2012/02/20(月) 22:05:43.26
>>347 see man test
0350名無しさん@お腹いっぱい。2012/02/20(月) 22:38:49.99
>>347
つまんねー。矢吹先生の方が数段上。
0351名無しさん@お腹いっぱい。2012/02/22(水) 17:59:45.94
-fのfは普通のf
■ このスレッドは過去ログ倉庫に格納されています