シェルスクリプト総合 その6
■ このスレッドは過去ログ倉庫に格納されています
0001うはwwwww
2006/03/26(日) 00:56:22スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
0207名無しさん@お腹いっぱい。
2006/04/04(火) 12:17:570208名無しさん@お腹いっぱい。
2006/04/04(火) 12:19:06早とちり厨ハケン。質問欲嫁。
0209名無しさん@お腹いっぱい。
2006/04/04(火) 12:23:570210名無しさん@お腹いっぱい。
2006/04/04(火) 12:25:260211名無しさん@お腹いっぱい。
2006/04/04(火) 12:30:23かな?
0212名無しさん@お腹いっぱい。
2006/04/04(火) 12:33:18んなん、forで回せばいいだろ。
0213名無しさん@お腹いっぱい。
2006/04/04(火) 12:38:52tar -c hoge.txt aaa/fuga.txt bbb/ccc/boke.txt |(cd /dokoka/sonohen; tar xf -)
で済むんだけど、使わないのは宿題かなんか?
0214名無しさん@お腹いっぱい。
2006/04/04(火) 12:45:16GNU cpなら、
cp --parents hoge.txt aaa/fuga.txt bbb/ccc/boke.txt /dokoka/sonohen
だな。
>>211
GNU cpだと、-Pはシンボリックリンク保存オプションなので違うと思うが。
0215名無しさん@お腹いっぱい。
2006/04/04(火) 12:59:33tarが無しな理由は、コピー元ファイルがシンボリックリンクだった場合に、
実体ファイルに展開して欲しいからです。
>>214
ありがとうございます。でもGNU cpが無い場合はどうすればいいですか?
0216名無しさん@お腹いっぱい。
2006/04/04(火) 13:11:00symlinkだけの問題なら tarに hオプションを付ければいい。
でも cp --parentsが使える環境ならその方が簡単。
0217名無しさん@お腹いっぱい。
2006/04/04(火) 21:31:16シェルってゆうな。クズ。
0218名無しさん@お腹いっぱい。
2006/04/04(火) 21:37:47残念。この場合は「シェル」でもOK。
0219名無しさん@お腹いっぱい。
2006/04/04(火) 22:26:220220名無しさん@お腹いっぱい。
2006/04/04(火) 22:40:27シェルとシェルスクリプトの違いもわからんのか?
0221名無しさん@お腹いっぱい。
2006/04/04(火) 22:44:29>>206 の質問だと、シェルスクリプトにせずに
直接コマンド(シェルの構文を含む)を打つとも解釈できるから、
「シェル」でもOKと思われ。
それより、いちいち「シェルってゆうな」の反応の方が鵜剤。
0222名無しさん@お腹いっぱい。
2006/04/04(火) 22:55:16シェルスクリプトをシェルと言う馬鹿が絶えないのがそもそもの原因であって、
それを指摘するほうにいちいちつっかかるほうが間違い。
0223名無しさん@お腹いっぱい。
2006/04/04(火) 23:06:480224名無しさん@お腹いっぱい。
2006/04/04(火) 23:13:44そこでお聞きしたいのですが、皆さんが最初に書いたシェルは何ですか?
やっぱり、echo hello worldとかでしょうか?
0225名無しさん@お腹いっぱい。
2006/04/04(火) 23:19:43まず、その仕事とやらを紹介してみたまえ。
0226名無しさん@お腹いっぱい。
2006/04/04(火) 23:21:290227名無しさん@お腹いっぱい。
2006/04/05(水) 01:37:57正解!
0228名無しさん@お腹いっぱい。
2006/04/05(水) 07:04:12つまんねーんだよ
死ねデブ
0229前.ス.レ.の.ク.ラ.ッ.カ.ー
2006/04/05(水) 15:26:02俺の方がよっぽどスキルある。
0230名無しさん@お腹いっぱい。
2006/04/05(水) 15:39:25UNIXはじめました
と春になると焼き肉屋に案内が出ますが
どっちがブちがいがありますか?
0231名無しさん@お腹いっぱい。
2006/04/05(水) 16:14:33ネットワーク管理で使うUNIXはパターンが限られているので、
よく使うUNIXを、コメントとともにメモ帳などで保存しておけば良い。
で、これを適宜、TELNETにコピペしてUNIXを打つ。
変にシェルを作っても、そのシェルの名前を忘れそうだし、
シェル自体がブラックボックスになって、結局使わなくなってしまうのがオチだよ。
0232名無しさん@お腹いっぱい。
2006/04/05(水) 16:26:39じゃシェルはぶたなくても良いのね
UNIXを6回くらいぶつのをまとめて
スクリプトにしたいんだけど使うときは
UNIXをぶつで良いの?
0233名無しさん@お腹いっぱい。
2006/04/05(水) 17:10:040234名無しさん@お腹いっぱい。
2006/04/05(水) 18:12:380235名無しさん@お腹いっぱい。
2006/04/05(水) 18:38:29シェルの中で shを実行すれば UNIXが出せる。
UNIXを終る時は exitを打てば、シェルに戻る。
0236名無しさん@お腹いっぱい。
2006/04/05(水) 22:29:44シェ
シェル
シェス
シェスク
シェルスクリ
スクリプト
プト
どれが正しいですか?
0237名無しさん@お腹いっぱい。
2006/04/05(水) 22:36:520238名無しさん@お腹いっぱい。
2006/04/05(水) 22:49:54ェルスクリプ
0239名無しさん@お腹いっぱい。
2006/04/05(水) 22:51:37「スクリプト」と略すのはありだと思うよ。
そういう場合でも、「シェル」と略すのはまずいと思われ。
ただ、スクリプトだけだと、perl とか ruby のスクリプトも
含まれるから、あくまで文脈からシェルスクリプトだと分かる場合
のみ。
0240名無しさん@お腹いっぱい。
2006/04/05(水) 23:10:51クリ
0241名無しさん@お腹いっぱい。
2006/04/06(木) 00:04:20ただ発言者の人格や知性が疑われることはあるだろうが、それもまたよし。
0242名無しさん@お腹いっぱい。
2006/04/06(木) 00:17:51UNIXとシェルの使い方が少しラフだ
0243名無しさん@お腹いっぱい。
2006/04/06(木) 10:36:15それがkshなりperlやpythonで記述されてるかどうかなんてふつう気にする?
>>236
シエル
0244名無しさん@お腹いっぱい。
2006/04/06(木) 11:12:060245名無しさん@お腹いっぱい。
2006/04/06(木) 11:27:20先輩のことかーっ!!
0246名無しさん@お腹いっぱい。
2006/04/06(木) 11:47:25シェルを作られる方がガマンできる
0247ななし
2006/04/06(木) 16:54:17[ $1 = -a ] とやるとうまくいきません。
何かいい方法はありませんか?
0248名無しさん@お腹いっぱい。
2006/04/06(木) 17:11:260249名無しさん@お腹いっぱい。
2006/04/06(木) 17:20:01現行のシェルだとそのままでうまくいく。
うまく行かないのはかなり古いBourne Shell。
ちなみにどのOSのshか教えて。
うまく行かないシェルの場合は、
[ X"$1" = X-a ]
とやって回避する。が、この回避方法はバッドノウハウなので、
もうobsoleteなはずなんだが、、
0250名無しさん@お腹いっぱい。
2006/04/06(木) 17:24:13なんで廃れたとか原始的とか古典的とか
爺さんの知恵袋とか
文脈に的確な日本語を当てないで
【obsolete】なんて形容詞や動詞として使うの?
0251名無しさん@お腹いっぱい。
2006/04/06(木) 17:33:48イマドキのシェルだと、>>249 の回避方法を使わなくても
そのままで桶なはずだが、それ以前の問題として、
$1を " " で囲んだ方がいい。
[ "$1" = -a ] ね。
でないと、$1が -aだった場合じゃなくて、
$1がスペースだった場合とかにエラーになる。
0252名無しさん@お腹いっぱい。
2006/04/06(木) 23:40:45.sh
0253名無しさん@お腹いっぱい。
2006/04/07(金) 00:01:00重箱の隅をつついいてひとり悦に入る非生産的な奴だね君
0254名無しさん@お腹いっぱい。
2006/04/08(土) 00:33:08>cp -p hoge.txt aaa/fuga.txt bbb/ccc/boke.txt /dokoka/sonohen
>を実行すると、hoge.txt fuga.txt boke.txtが、
>bbb/ccc/boke.txtは /dokoka/sonohen/bbb/ccc/boke.txtに、
>コピーしたいのです。
find hoge.txt aaa/fuga.txt bbb/ccc/boke.txt -print -depth | cpio -pdmuv /dokoka/sonohen
でできる。
コピー元がリンクなら、コピー後もリンクのまんまだよ。
0255名無しさん@お腹いっぱい。
2006/04/08(土) 07:52:08欲嫁。>>206 に「tar等を使うのは無しで」とある。
tar等には cpioも含まれると思われる。
それに、コピー後もsymlinkのままでは困るという質問だよ。
(ファイル本体をコピーして欲しいというのが質問の意図)
で、>>214 の cp --parents ですでに解決済み。
0256名無しさん@お腹いっぱい。
2006/04/09(日) 18:49:03権限関係の理由で sudo と expect を使って
パスワード認証を行ってから cat する方法を取りたいと考えています。
cat だけなら問題ないのですが、
# cat A > hoge1.txt
# ./cat.exp ID PASS A > hoge2.txt
上記のようにした場合、
hoge2.txt の方が10〜300バイトほど量が増えてしまいます。
おそらくcat.expの中で無駄な出力が出てしまっているためかと
思うのですが、改善方法を教えていただけないでしょうか?
expectのマニュアルを見ましたが解決しません
ttp://kansai.anesth.or.jp/gijutu/expect/howto-expect.html
--cat.exp--------------------------------------
#!/usr/bin/expect
set username [lindex $argv 0]
set password [lindex $argv 1]
set file [lindex $argv 2]
log_user 0
spawn sudo -u $username /bin/cat $file
expect "assword:"
send "$password\r"
expect eof
log_user 1
exit
0257名無しさん@お腹いっぱい。
2006/04/09(日) 19:20:40expectだと改行コードがCR+LFで記録されてしまうからじゃないの?
0258256
2006/04/09(日) 22:49:06レスありがとうございます、
関連情報を調べてみようと、改行コード expect あたりでぐぐったのですが
特に見つかりませんでした。
直す方法はあるでしょうか?
0259名無しさん@お腹いっぱい。
2006/04/09(日) 22:53:090260256
2006/04/09(日) 23:30:18できるだけ出力後に処理ってのは勘弁を・・・orz
0261名無しさん@お腹いっぱい。
2006/04/10(月) 00:12:460262名無しさん@お腹いっぱい。
2006/04/10(月) 03:15:58sudo がパスワード認証するんだから、
#!/bin/sh
sudo -u ahouser cat "$@"
でいいじゃん。
パスワードをコマンドラインから入れたら、ps で「もろばれ」なのはわかってんの? それでも、やりたいんだったら、sudo -S っていう手があるけどさ。正気ならそんなことしない。
どうしても、その狂気を避けられないのは「権限関係の設計が悪い」からです。僕
だったら、wrapper作るか、.ssh 作ってssh 経由でcatさせるね。
0263名無しさん@お腹いっぱい。
2006/04/10(月) 10:22:34移動先のディレクトリでも、シンボリックリンクが正しく元のファイルを
指すようにするには、どういうシェルを書けばいいでしょうか?
シンボリックリンクが絶対パスなら無問題ですが、
シンボリックリンクは、../.. とかを含む相対パスであり、
かつ、移動先でも相対パスでリンクする必要があります。
例えば、
/aaa/bbbディレクトリの下に
hoge -> ../hage
というシンボリックリンクがあったとすると、
これを/aaa/ccc/dddディレクトリの下に移動させた場合、
今度は、
hoge -> ../../hage
を指すようにリンクを修正して移動したいのです。
0264名無しさん@お腹いっぱい。
2006/04/10(月) 13:03:090265名無しさん@お腹いっぱい。
2006/04/10(月) 13:20:31それでは解決にならんよw
0266名無しさん@お腹いっぱい。
2006/04/10(月) 20:14:200267名無しさん@お腹いっぱい。
2006/04/11(火) 03:19:210268名無しさん@お腹いっぱい。
2006/04/11(火) 12:04:20Macでこれが失敗した。
/bin/test -z = -a -o -f /etc/passwd
POSIXでも引数がたくさんある場合の評価の順序はunspecified。
0269名無しさん@お腹いっぱい。
2006/04/12(水) 01:38:08下記の方法でスクリプトを書いてみたのですが、
改行のみの行が処理対象とすることができません。
#==ファイルの中身===
$ cat hoge.dat
111
222
333
444
#==スクリプトの中身===
#!/usr/local/bin/bash
IFS='
'
for line in `cat hoge.dat`
do
echo $line
done
#==実行結果 ここまで===
111
222
333
444
なぜ、222と333の間の改行のみの行がわたってこないのでしょうか?
0270名無しさん@お腹いっぱい。
2006/04/12(水) 01:40:252ちゃんめるって、インデントが向こうになるんですか?
[半角空白][半角空白][半角空白][半角空白]echo $line
ってかいたのに
echo $line
になってる。
0271>>269
2006/04/12(水) 01:54:27ループの部分を以下のように変更したら、うまくいきました。
while read LINE
do
echo $LINE
done < hoge.dat
0272名無しさん@お腹いっぱい。
2006/04/12(水) 01:59:36ようなIFSでも、並んだ空白文字であればいくつでも無視するでしょ? それと一緒。
0273名無しさん@お腹いっぱい。
2006/04/12(水) 03:34:32定番だが、$LINE は "$LINE" にしておいた方が幸せだ。
0274名無しさん@お腹いっぱい。
2006/04/12(水) 10:32:510275名無しさん@お腹いっぱい。
2006/04/12(水) 11:48:34実行オプションがあるのに、オプション"--"を許容できないのが設計ミスのような。
0276名無しさん@お腹いっぱい。
2006/04/12(水) 11:54:41それはbashだけの問題ではない。zshやashとかでも同じ問題がある。
Solarisのshだと-nの問題はないが、代わりに、
$LINEの中身が \c とかだとやはり問題になる。
元はechoコマンドの設計ミスだが、今さらもう変えられないのが現実。
で、echoの代わりにprintfを使えというのが今の結論だが、
シェルによってはprintfが組み込みじゃないので、
使うのはためらわれる。
0277名無しさん@お腹いっぱい。
2006/04/12(水) 16:25:07今までUNIXとかぜんぜんやったことなくて何がなんだかで途方にくれてます。
そもそも質問自体どうやっていいかわけがわかってないんですが、どなたかヒントだけでもいただけませんでしょうか。
登録するリストは別にあって、だいたい800ぐらいなんです。
メールアカウントを個々に登録することは
# useradd.sh NEWUSERACCOUNT@***.***.***.jp PASSWORD
Creating user.NEWUSERACCOUNT on default
add NEWUSERACCOUNT
ってな感じで登録してるんですが・・・・。
これだけで何が言いたいかわかるでしょうか。
そもそもこのスレでいいかどうかもわかりませんが、本当に申し訳ないですがわかる方いましたらよろしくお願いいたします。
0278名無しさん@お腹いっぱい。
2006/04/12(水) 16:41:25えっと、useradd.sh というスクリプトは、お前の会社とかで作成された
スクリプトだな。(一般のuseraddコマンドとは無関係)
で、
useradd.sh メールアドレス パスワード
という書式で実行すればいいんだな。
だとすると、その800アカウント分くらいあるという、
別ファイルのリストの書式を晒せ。
そのリストを読んで、useradd.shを呼び出しながらループする
シェルスクリプトを書けば桶。
0279名無しさん@お腹いっぱい。
2006/04/12(水) 16:43:40while read x
do useradd.sh $x
done < 登録するリスト
0280名無しさん@お腹いっぱい。
2006/04/12(水) 16:45:34そのリストは、
user1@example.com パスワード1
user2@example.com パスワード2
:
という書式だとエスパーしてみる。
すると、
while read addr pass
do
useradd.sh "$addr" "$pass"
done < リストのファイル名
でOKだよ。
もし、リスト中に余分な文字列があるなら、それを取り除く処理が必要。
0281名無しさん@お腹いっぱい。
2006/04/12(水) 16:53:01もしそういう書式なら
エディタで行頭に "useradd.sh " を追加して
そのままシェルスクリプトとして実行しちゃうのが楽。
0282名無しさん@お腹いっぱい。
2006/04/12(水) 17:06:41xargs -n2 useradd.sh < 登録するリスト
0283名無しさん@お腹いっぱい。
2006/04/12(水) 17:10:08リストをエディットして直接実行する場合、
パスワード部分の文字列が、
z3xd89;rm -rf /;Eakez
とかになっていると面白いことになりそう。
0284277
2006/04/12(水) 18:15:08リスト自体は
user1 password1
user2 password2
・ ・
・ ・
・ ・
といった感じですが、@以下も追加しちゃえばよさそうですかね。
とりあえずがんばってやってみます。
こんな初心者に教えていただきありがとうございます。
また何か困ったらお願いしたいと思いますが、できるだけ自分でできるようがんばります。
0285名無しさん@お腹いっぱい。
2006/04/12(水) 18:20:21だったら、>>280 の回答が近い。
while read addr pass
do
useradd.sh "$addr"@example.com "$pass"
done < リストのファイル名
とすればいい。リストのエディットは不要。
0286名無しさん@お腹いっぱい。
2006/04/12(水) 18:21:59おれが透視したところによると
そういう行は存在しないので無問題。
0287名無しさん@お腹いっぱい。
2006/04/12(水) 20:11:07python -c 'print __import__("sys").stdin.read()' |
ruby -e 'while gets(); print $_ end' |
sh -c 'while read x;do echo $x;done' |
awk '{print}' |
perl -pe '' |
sed '' |
cat
全部読み込むまでパイプしない奴は誰でしょう。(10点)
0288名無しさん@お腹いっぱい。
2006/04/12(水) 20:17:04答え、python。
つーか、答がpythonになるなら、それはpythonのバッファリングの問題であって、
シェルスクリプトスレとしてはスレ違い。
0289名無しさん@お腹いっぱい。
2006/04/12(水) 20:23:36毎度お約束だが、echo $x は echo "$x" にしておいた方が幸せだ。
0290名無しさん@お腹いっぱい。
2006/04/12(水) 20:26:58早い正解!よくわかったね、スレ違い恐縮です
0291名無しさん@お腹いっぱい。
2006/04/12(水) 20:33:32いろんなコマンドで catモドキを作るというのも面白そうかも。
とりあえず、
tr a a とか、
nkf -Jj とか。
0292名無しさん@お腹いっぱい。
2006/04/12(水) 20:41:20grep ''
dd 2> /dev/null
(ddはメッセージを捨てる必要あり)
0293名無しさん@お腹いっぱい。
2006/04/12(水) 21:00:41uuencode hoge | uudecode -p
こういう組み合わせはいくらでもあるので以後禁じ手で。
0294名無しさん@お腹いっぱい。
2006/04/12(水) 21:03:33ダウト! nkf -Jj は変換されてしまう。
俺からもひとつ、
tail +1
0295名無しさん@お腹いっぱい。
2006/04/12(水) 21:16:010296名無しさん@お腹いっぱい。
2006/04/12(水) 22:01:310297名無しさん@お腹いっぱい。
2006/04/12(水) 23:19:45bash -c 'echo "`</dev/stdin`"'
0298名無しさん@お腹いっぱい。
2006/04/12(水) 23:47:340299名無しさん@お腹いっぱい。
2006/04/12(水) 23:56:25「2chは匿名だからこんなに殺伐としているんだ」
みたいな意見は嘘だと分かるよな。
fjは実名であんなに殺伐とできたのだから。
0300名無しさん@お腹いっぱい。
2006/04/13(木) 00:39:57やっぱり一般のプロバイダが参入してきて
fjも匿名が当たり前になってからじゃない?
0301名無しさん@お腹いっぱい。
2006/04/13(木) 00:42:23は違和感ある。
nifty→今の2ch
fj→スラド
でしょ。
0302名無しさん@お腹いっぱい。
2006/04/13(木) 00:56:08helloだとインがないからプログラムらしく見えなかったのか
catもどきだとその処理系の癖が見えて詳しくなった気分
0303名無しさん@お腹いっぱい。
2006/04/13(木) 01:15:58tee
0304256
2006/04/13(木) 10:56:14うわ、言われてみれば・・・・・。
こうしたほうがsudoの場合でもセキュリティ十分に確保できると
思ってやってたんですが、psで簡単にばれちゃうとは本末転倒ですね。orz
0305名無しさん@お腹いっぱい。
2006/04/13(木) 16:43:52パソコン通信の連中が入ってきてからは、ゴミ記事と馬鹿が増えたっけ
げいいんが変換できないのはおかしい、とか
0306名無しさん@お腹いっぱい。
2006/04/13(木) 19:25:56といったところ?
■ このスレッドは過去ログ倉庫に格納されています