シェルスクリプト総合 その5
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
2006/01/21(土) 09:00:29スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。
□お約束
・特記なき場合はbourne shがデフォルトです。
bash/csh/tcsh/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
0251名無しさん@お腹いっぱい。
2006/02/21(火) 10:31:120252名無しさん@お腹いっぱい。
2006/02/21(火) 10:32:060253名無しさん@お腹いっぱい。
2006/02/21(火) 10:42:36それ最初に思いついたのですが、
ls: 0653-341 ファイル /home/usr/ini/*.ini が存在しません。
のようにファイルが存在しない場合実現できません。
>>252
それよくわからんのですが、今の環境じゃ使えなさそうです。
AIX 5.2
0254名無しさん@お腹いっぱい。
2006/02/21(火) 10:46:16ls /home/usr/ini/*.ini 2>/dev/null
0255名無しさん@お腹いっぱい。
2006/02/21(火) 10:49:04ls: asdf*wqerty: そのようなファイルやディレクトリはありません
$ bash -c 'shopt -s nullglob; echo asdf*wqerty'
$ bash -c 'shopt -u nullglob; echo asdf*wqerty'
asdf*wqerty
0256名無しさん@お腹いっぱい。
2006/02/21(火) 10:53:36なるほど。これがシンプルでいいですね。
>>255
ほぉこんなのがあるのですね。
参考にさせていただきます。
こんな質問に答えてくれたかたありがとうございました。
0257名無しさん@お腹いっぱい。
2006/02/21(火) 10:56:110258名無しさん@お腹いっぱい。
2006/02/21(火) 12:11:340259名無しさん@お腹いっぱい。
2006/02/21(火) 12:23:570260名無しさん@お腹いっぱい。
2006/02/21(火) 12:26:51depth の
ディレクトリ本体の前に、ディレクトリの内容を先に評価する。
意味がよくわからんのですが、教えてください。
これで>>250可能なんすか?
0261名無しさん@お腹いっぱい。
2006/02/21(火) 12:30:04-depthはdepth firest search。指定しないとbreadth first search。
0262名無しさん@お腹いっぱい。
2006/02/21(火) 13:19:090263名無しさん@お腹いっぱい。
2006/02/21(火) 16:26:10hostコマンドを使うとしても、CNAMEが絡んでいたりすると
その標準出力の書式が一定せず、かといってdigコマンドでは
無駄な情報が多過ぎて切り出しが大変です。
さらに、bindのバージョンによってもhostやdigの出力が微妙に違うようです。
もっと言うと、DNSに登録されていなくて、/etc/hostsにのみ存在するホスト名でも
IPアドレスに変換したいのですが、となると、host/digコマンドは使えません。
シェルでIPアドレスに変換するには、どうやるのが一般的ですか?
あ、シェルで無理なら、エネオスでもジョモでもいいです。
0264名無しさん@お腹いっぱい。
2006/02/21(火) 16:55:220265名無しさん@お腹いっぱい。
2006/02/21(火) 20:30:29… という冗談はさておき、本当はどうやるのが一般的でしょうか?
0266名無しさん@お腹いっぱい。
2006/02/21(火) 20:36:14でもホスト名−IPアドレスってのは一意に決まらんと思う。
DNSでロビンちゃんしてたらどうするの?
0267名無しさん@お腹いっぱい。
2006/02/21(火) 20:47:27だと、実際には2行目以降が出力されて初めてパイプが終了するため、
取得に1秒程度かかってしまいます。
さらに、hostが立ち上がっていなかったり、firewallでpingが閉じられていると
2行目が出力されないため、head -1 が終了しません。
タイムアウトまで待てば終了するでしょうが、これでは使いものになりません。
0268名無しさん@お腹いっぱい。
2006/02/21(火) 20:54:03ホストのダウン対策は -t 1
0269名無しさん@お腹いっぱい。
2006/02/21(火) 21:02:03これって標準コマンドじゃないのかな。
0270名無しさん@お腹いっぱい。
2006/02/21(火) 21:04:56とか。
ロビンちゃん問題もどうするのか書いてないしどーでもいいけどな。
0271名無しさん@お腹いっぱい。
2006/02/21(火) 22:43:240272名無しさん@お腹いっぱい。
2006/02/21(火) 23:06:070273名無しさん@お腹いっぱい。
2006/02/21(火) 23:44:240274名無しさん@お腹いっぱい。
2006/02/22(水) 00:20:340275名無しさん@お腹いっぱい。
2006/02/22(水) 00:21:410276名無しさん@お腹いっぱい。
2006/02/22(水) 00:56:53getentがどこにもあれば一番いいと思うけれど。
0277名無しさん@お腹いっぱい。
2006/02/22(水) 01:06:470278名無しさん@お腹いっぱい。
2006/02/22(水) 02:05:26Linux だけど、gethostipインストールされてないです。
ちなみに Debian 3.1 (sarge)。
0279名無しさん@お腹いっぱい。
2006/02/22(水) 02:08:370280名無しさん@お腹いっぱい。
2006/02/22(水) 02:19:08root じゃないので、インストールできません…
0281名無しさん@お腹いっぱい。
2006/02/22(水) 02:27:040282名無しさん@お腹いっぱい。
2006/02/22(水) 02:28:20$ getent hosts www.2ch.net
でええやろ
0283名無しさん@お腹いっぱい。
2006/02/22(水) 09:37:48俺はこんなの自作して使ってるが。
#!/bin/sh
echo -n "Enter lines to get: "
read lines
iplist=`ssh hoge@hogehoge.org tail -$lines /var/log/httpd/access_log
| cut -f1 -d¥ `
for ip in $iplist
do
ipout=`host $ip | grep pointer | awk '{print($5)}' |
grep -v NXDOMAIN | sed "s/.$//g"`
if test "$ipout" = ""
then
echo "$ip"
else
echo "$ipout"
fi
done
0284名無しさん@お腹いっぱい。
2006/02/22(水) 09:45:49host じゃ /etc/host 見ないっしょ。
0285名無しさん@お腹いっぱい。
2006/02/22(水) 10:54:43getent hosts いいですね。glibcの付属コマンドみたいですね。
ただ、getent hostsでは、ごくたまーに、IPv6が登録されてるホストだと、
IPv6だけが引けて、IPv4が(登録されてるのに)引けません。
gethostipだと、IPv6は無視してIPv4のみが引けます。
どうすればいいでしょうか?
0286名無しさん@お腹いっぱい。
2006/02/22(水) 11:06:21・/etc/hostsは優先かどうか?
・v4/v6は両方欲しいのか、片方だけか。
0287名無しさん@お腹いっぱい。
2006/02/22(水) 11:11:39IPv4だけが欲しい。なるべくOS非依存にしたい。です。
0288名無しさん@お腹いっぱい。
2006/02/22(水) 11:43:46バージョンによる差異が無視できるかどうかがポイントか。
RubyでもPythonでもいいんだけど、入ってないことも多いし。
0289名無しさん@お腹いっぱい。
2006/02/22(水) 11:55:210290名無しさん@お腹いっぱい。
2006/02/22(水) 12:04:320291名無しさん@お腹いっぱい。
2006/02/22(水) 12:46:20ロビンちゃん問題はどうするんだよ!!
0292名無しさん@お腹いっぱい。
2006/02/22(水) 13:02:160293名無しさん@お腹いっぱい。
2006/02/22(水) 13:07:290294名無しさん@お腹いっぱい。
2006/02/22(水) 13:08:030295名無しさん@お腹いっぱい。
2006/02/22(水) 18:14:50ソフトリンクのみリストアップするシェルって、どう書けばいいですか?
0296名無しさん@お腹いっぱい。
2006/02/22(水) 18:18:27英語に親しんでおけって。
あ、スクリプトじゃなくてシェルを作るのか。bisonやflexについて
調べるのかな。まあどうでもいいことだけど。
0297名無しさん@お腹いっぱい。
2006/02/22(水) 18:22:43find . -type s | while true; do read x; ls -L $x >/dev/null; done | awk '{ print $2 }' | sed 's/:$//'
0298名無しさん@お腹いっぱい。
2006/02/22(水) 18:23:13find . -type l
や、
find . -follow -type l
ではできないことを確認の上で聞いてます。
ちなみに、英語は得意です。
0299名無しさん@お腹いっぱい。
2006/02/22(水) 18:23:560300名無しさん@お腹いっぱい。
2006/02/22(水) 18:25:16-type s ってUNIXドメインソケットなんですが、、
それ違うでしょう。
あと、ファイル名に空白があると誤動作するんじゃ困ります。
0301名無しさん@お腹いっぱい。
2006/02/22(水) 18:31:500302名無しさん@お腹いっぱい。
2006/02/22(水) 18:42:08ある程度自分でも書いてみたんでしょ? 晒してみなよ。 勇気だしてさ。
0303名無しさん@お腹いっぱい。
2006/02/22(水) 18:55:06find . -type l -exec sh -c '[ -e "{}" ] || echo "{}"' ';'
0304名無しさん@お腹いっぱい。
2006/02/22(水) 18:57:31#! /bin/sh
ls -L "$1"
if [ $? -ne 0 ]; then
echo "$1"
fi
をxargsで-0 -n 1だな。
0305名無しさん@お腹いっぱい。
2006/02/22(水) 19:11:33「ここで質問する時は敢えて『シェルを書く』と言うと、回答の食いつきが良い」
急ぎで回答を得たい場合にもお勧め。
φメモメモ。
0306名無しさん@お腹いっぱい。
2006/02/22(水) 19:15:06使ってるのは何故だか、理解してる?
知らなくても問題ない。man xargsだ。
0307名無しさん@お腹いっぱい。
2006/02/22(水) 19:31:57ほのめかし厨さん
0308名無しさん@お腹いっぱい。
2006/02/22(水) 19:46:57-execがあるだろうとかそんなことでしょ。
けどエスケープやエクスパンジョンの泥沼にはまるくらいなら、
xargsはええと思うで。stdinからexecveまでshellを介さんから。
特に空白や日本語や特殊文字のパス名が多い昨今は。
0309295
2006/02/22(水) 19:48:22↓これで一発です。
for file in *; do [ -h "$file" -a ! -e "$file" ] && echo "$file"; done
findなどの外部コマンドは使いませんし、
スペース入りファイル名の問題もありません。
釣られて回答をくれた皆さん、釣りには気をつけましょう。
0310名無しさん@お腹いっぱい。
2006/02/22(水) 20:24:03ln -s /nonexistent .詰めが甘いな坊や
0311名無しさん@お腹いっぱい。
2006/02/22(水) 20:34:32どう詰めが甘いの?
ln -s /nonexistent . でも、期待通り動作するけど。
0312名無しさん@お腹いっぱい。
2006/02/22(水) 20:51:430313名無しさん@お腹いっぱい。
2006/02/22(水) 21:01:00なんだそんなことか。
.で始まるファイルはここでは問題になってないので、、、
必要なら for file in * .* にすればいいだけだし。
0314名無しさん@お腹いっぱい。
2006/02/22(水) 21:03:30仕様後付けで「期待通り」なんて言っているから坊やなんだよ。
0315名無しさん@お腹いっぱい。
2006/02/22(水) 21:10:01メインであって、それ以外の部分は参考でしかない。(仕様のあと付けではない)
>>310 みたいな突っ込みは本筋以外の部分に突っ込んでるので、
突っ込みとしても、釣りとしても面白くない、詰まり詰めが甘い。
0316名無しさん@お腹いっぱい。
2006/02/22(水) 21:15:530317名無しさん@お腹いっぱい。
2006/02/22(水) 21:19:510318名無しさん@お腹いっぱい。
2006/02/22(水) 21:27:23今度はどんなシェルを書きたいのですか?
0319名無しさん@お腹いっぱい。
2006/02/22(水) 21:32:38引っ掛け問題なので、それ以外の部分は障害物でしかない。(仕様のあと付けではない)
0320名無しさん@お腹いっぱい。
2006/02/22(水) 21:38:200321名無しさん@お腹いっぱい。
2006/02/22(水) 22:20:27それとも、犬の馬鹿が乱入して吠えてるというのは僕の妄想であって、
本当はUNIX板の住人がこうして基地外みたいに吠えてるのでしょうか?
0322名無しさん@お腹いっぱい。
2006/02/22(水) 22:34:340323名無しさん@お腹いっぱい。
2006/02/22(水) 22:42:150324名無しさん@お腹いっぱい。
2006/02/23(木) 00:04:24このスレの馬鹿は半分しか減らないよ。
0325名無しさん@お腹いっぱい。
2006/02/23(木) 00:09:18すぐに犬糞とか言い出すヤツ。何なのアレ?
0326名無しさん@お腹いっぱい。
2006/02/23(木) 00:12:380327あい
2006/02/23(木) 20:28:26それとAIXのdateコマンドを使用して二ヶ月前の日付を取得できないでしょうか?
0328名無しさん@お腹いっぱい。
2006/02/23(木) 20:51:38find で -ctime とか -mtime 指定したんじゃまずいのか?
0329名無しさん@お腹いっぱい。
2006/02/23(木) 21:28:292ヶ月前の日付は、TZいじって、
TZ=JST+1431 date でできない?
できなきゃあきらめて GNU dateを入れて date -d '2 months ago'
0330名無しさん@お腹いっぱい。
2006/02/24(金) 09:26:45getentコマンドはSolarisにもあるよ。他のOSでは未確認だけど、
OS依存性を小さくしたいのならgetentでいいんじゃない?
IPv6を設定しているような変態ホストは無視しても問題なし。
0331名無しさん@お腹いっぱい。
2006/02/24(金) 09:47:362 host -t aで引く(IPv4オンリー、ラウンドロビン)
1がIPv6なら、2のみ
それ以外、1と2をmerge&uniq
ってスレ違いじゃねえ?
0332名無しさん@お腹いっぱい。
2006/02/25(土) 00:40:49OpenSSLの自己証明書を作成するときなど
自己証明の入力を促されますが
シェルスクリプトで自動で入力するようにしたいです。
どうやったらできるでしょうか?
ご教授よろしくお願いします。
0333名無しさん@お腹いっぱい。
2006/02/25(土) 00:56:49expectスクリプトだな。
0334名無しさん@お腹いっぱい。
2006/02/25(土) 01:00:37> 自己証明の入力を促されますが
何言ってんだか分からないが、引数で渡せないのか?
それともバカチョンスクリプト、CA使ってんの? 自分でやれ
0336名無しさん@お腹いっぱい。
2006/02/25(土) 01:18:550337名無しさん@お腹いっぱい。
2006/02/25(土) 01:40:37Ctrl-C Ctrl-V
0338332
2006/02/25(土) 01:53:50expect勉強して、testuserのパスワード変更スクリプト作ったのですがうまくいきません。
#!/bin/sh
USER=testuser
PASSWD=testpass
expect -c "
set timeout 20
spawn passwd $USER
expect \"New UNIX password:\"
send \"$PASSWD\r\"
expect \"Retype new UNIX password:\"
send \"$PASSWD\r\"
"
これを実行すると何もエラーなく終了するのに
パスワードは変わってません。
どこか間違ってるでしょうか?
よろしくお願いします。
0339名無しさん@お腹いっぱい。
2006/02/25(土) 02:07:230340名無しさん@お腹いっぱい。
2006/02/25(土) 02:17:33>>337は実行したのか?
0341名無しさん@お腹いっぱい。
2006/02/25(土) 08:35:39「強制終了」と、「コントロールコード1字入力」が、
この文脈で何か関係あるのか?
0342名無しさん@お腹いっぱい。
2006/02/25(土) 09:43:130343332
2006/02/25(土) 10:23:13expect -c "
set timeout 20
spawn passwd testuser
expect "*password*"
send "test"
expect "*password*"
send "test"
"
expect使ったことないのでよくわからないのですが、こんな感じですよね?
でもこれ実行してもパスワード変わってないのです。
どなたか、ご教授よろしくお願いします。
0344名無しさん@お腹いっぱい。
2006/02/25(土) 10:43:490345名無しさん@お腹いっぱい。
2006/02/25(土) 23:26:59user $
みたいに&付ければ作ったスクリプトを常駐できるのですが、
&なしで
user $ test.sh
user $
のように&なしで常駐するようなスクリプトはどう書けばいいのですか?
0346名無しさん@お腹いっぱい。
2006/02/25(土) 23:32:04スクリプトの中で & を付けてコマンドを起動すればいいだけ。
コマンドが複数ある場合は、( ) で囲って最後に &
↓みたいな感じ
(
command1
command2
:
:
) &
0347名無しさん@お腹いっぱい。
2006/02/25(土) 23:43:53素早い解答ありがとうございます。
0348名無しさん@お腹いっぱい。
2006/02/26(日) 10:50:210349名無しさん@お腹いっぱい。
2006/02/26(日) 12:33:090350名無しさん@お腹いっぱい。
2006/02/26(日) 12:37:53常駐=daemonという意味なら、むしろわざわざfork()して、
その親が先にexit()するというお決まりのプロセスを踏むのが普通。
ttyやプロセスグループを切り離すためにね。
■ このスレッドは過去ログ倉庫に格納されています