シェルスクリプト総合 その22
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
2013/11/01(金) 07:58:50.52□お約束
・特記なき場合は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に逃げずにシェルスクリプトで処理するのが頭のいいやり方。
前スレ
シェルスクリプト総合 その21
http://toro.2ch.net/test/read.cgi/unix/1352973453/
0012名無しさん@お腹いっぱい。
2013/11/08(金) 16:21:43.15あるねw
0013名無しさん@お腹いっぱい。
2013/11/08(金) 16:57:46.840
$ test 012 -eq 12; echo $?
0
0014名無しさん@お腹いっぱい。
2013/11/08(金) 17:49:27.80あ、使ってる関数は自動変換するけど、10進数限定にもできて、testは限定されてた。
だからやっぱりないw
0015名無しさん@お腹いっぱい。
2013/11/09(土) 13:58:50.12"負数"が返ってきたらアウトだな
と思ったけど実行結果は必ず0か自然数なので問題なかった
0016名無しさん@お腹いっぱい。
2013/11/10(日) 17:23:11.15チェックして保証したいんだけど、なんかいい方法ある?
手抜きなんかしないで、ひとつひとつちゃんと
HOGE="PIYO"
みたいなフォーマットにのっとってることを
文法チェックして確認しないとだめ?
0017名無しさん@お腹いっぱい。
2013/11/10(日) 19:40:09.82任意の書式だと困難だと思うけど。
0018名無しさん@お腹いっぱい。
2013/11/11(月) 01:57:30.15何の設定ファイル?
0019名無しさん@お腹いっぱい。
2013/11/11(月) 09:45:35.560020名無しさん@お腹いっぱい。
2013/11/11(月) 10:08:05.710021名無しさん@お腹いっぱい。
2013/11/11(月) 15:43:09.06a="b" の範囲内ならgrepでできるかもしれない。
a=${hoge:=piyo} とかも許すなら、俺しらね。
さらにシェルで書けることならなんでもOKとするなら、
本気でパーズしなきゃだめだろ。
0022名無しさん@お腹いっぱい。
2013/11/11(月) 19:30:27.56「実行可能」ではないのでは?
0023名無しさん@お腹いっぱい。
2013/11/11(月) 20:16:49.220024名無しさん@お腹いっぱい。
2013/11/12(火) 21:21:47.340025名無しさん@お腹いっぱい。
2013/11/13(水) 12:42:19.69そうだね
>>21
設定ファイルとして使いたいけど実装は面倒なので実行で済ませたい
って横着な話が起点なので、いい方法がなければ自力でチェックします。
bash -r とか使えるかなと思ったけど無意味っぽかった
0026名無しさん@お腹いっぱい。
2013/11/13(水) 13:08:08.67自力でもそんなに難しくないんでは。
0027名無しさん@お腹いっぱい。
2013/11/20(水) 19:52:35.18for i in `seq 1 10`
do
何かのコマンド
sleep 1h
done
echo "finished" | write username
といったスクリプトを書いているのですが、このやり方だと
最後にコマンドを実行してから一時間、無駄に sleep してしまいます。
最後の sleep だけ実行しない方法はないでしょうか。
0028名無しさん@お腹いっぱい。
2013/11/20(水) 19:58:50.00変数 i<=9 のときにsleep 1h
か
i/=10の時に sleep 1h
0029名無しさん@お腹いっぱい。
2013/11/20(水) 20:00:40.20i=10
while
何かのコマンド
((--i)) && sleep 1h
do :; done
echo "finished" | write username
003027
2013/11/20(水) 20:07:56.43ですが、たびたびすいません。
実際に使っているスクリプトだと、ループの実行回数が不定な場合があるのです。
(行数が特定できないファイルからの読み込みとか)
最後のループでは sleep しない、という手段はあるでしょうか。
003127
2013/11/20(水) 20:19:58.58何とか工夫すれば、判定できないループってないかも……。
どうもお騒がせしました。
0032名無しさん@お腹いっぱい。
2013/11/20(水) 23:30:36.92((--i)) でiが0になる時、返り値1なんだ。
iが負の値になる時でも返り値0なのに、0になる時だけ特別なんですね。
0033名無しさん@お腹いっぱい。
2013/11/21(木) 00:11:48.01return status is 0; otherwise the return status is 1.
0034教えてくだしあ
2013/11/21(木) 23:17:15.63もっかい別のとこにping 成功⇒ログ出力 失敗⇒コマンド実行
こんな感じのスクリプト作りたいんだけど
pingの結果って$?に入るんだよね
これって複数あった場合どうすれば良いの?
0035名無しさん@お腹いっぱい。
2013/11/21(木) 23:18:56.88どういうこと?
0036名無しさん@お腹いっぱい。
2013/11/21(木) 23:21:59.47直前のコマンドの結果で毎回 $? が上書きされるだけ。
003734
2013/11/21(木) 23:26:22.051.ping打つ 成功⇒2へ 失敗⇒終了
↑ココの$?
2.ping打つ 成功⇒ログ書き込み 失敗⇒コマンド実行
↑ココの$?
で結果を分けて処理しようと考えてます。
根本的に考え方が違うなら考えを改めるよ
0039名無しさん@お腹いっぱい。
2013/11/21(木) 23:29:46.92>>36 の回答は理解できないの?
hoge=$? でコピーしておいてもいいし
004034
2013/11/21(木) 23:47:57.56ちなこれって、ここの住人はどんな感じで書くん?
ping -c 3 192.168.43.1 >/dev/null
PING1=$?
if
[ ${PING1} -eq "0" ];then
ping -c 1 192.168.254.100 >/dev/null
PING2=$?
if
[ ${PING2} -eq "0" ];then
echo Status=OK
exit
else
/etc/script/wol 192.168.254.255 10:78:D2:4B:D6:55
echo WAKE-ON-LAN
fi
else
echo NoThanks
exit
0041名無しさん@お腹いっぱい。
2013/11/22(金) 00:01:34.93if ping -c 1 192.168.254.100 >/dev/null; then
echo Status=OK
else
/etc/script/wol 192.168.254.255 10:78:D2:4B:D6:55
echo WAKE-ON-LAN
fi
else
echo NoThanks
fi
全角空白は置換してくれ。
004234
2013/11/22(金) 00:08:55.90意外とスクリプト面白いな
0043名無しさん@お腹いっぱい。
2013/11/22(金) 00:09:42.94どういうこと?
0044名無しさん@お腹いっぱい。
2013/11/22(金) 01:55:31.530045名無しさん@お腹いっぱい。
2013/11/22(金) 08:48:23.240046名無しさん@お腹いっぱい。
2013/11/22(金) 09:22:12.610047名無しさん@お腹いっぱい。
2013/11/22(金) 22:29:53.59>>43 [ ${PING1} -eq "0" ];これってpingの変数が0だったらって条件じゃないの?
1とか他の値だったら条件に合わないよね?
でも>>41のを見るとそんな条件なく成功=次へって感じに見えるけど
何処に条件が書いてあるん?
分かり易く教えてくだしあ
0048名無しさん@お腹いっぱい。
2013/11/22(金) 22:46:39.23[ ... ] の [ は、ifの文法じゃなくて [ という名前のコマンド。
0049名無しさん@お腹いっぱい。
2013/11/23(土) 00:18:20.980050名無しさん@お腹いっぱい。
2013/11/23(土) 00:33:47.23コピーかリンク。
] は関係ない。
0051名無しさん@お腹いっぱい。
2013/11/23(土) 00:41:18.75最後に ] という引数を要求するようになっている、という仕組み。
0052名無しさん@お腹いっぱい。
2013/11/23(土) 01:22:07.550053名無しさん@お腹いっぱい。
2013/11/23(土) 19:24:30.28if [ -f "$f" ]; then
echo "ファイル$fはある"
else
echo "ファイル$fはない"
fi
を実行すると、
ファイルはない
f=
if [ -f $f ]; then
echo "ファイル$fはある"
else
echo "ファイル$fはない"
fi
を実行すると、
ファイルはある
"$f" でないと「ある」になるんですが、
そんなファイルはないのに、なぜなんでしょう?
0054名無しさん@お腹いっぱい。
2013/11/23(土) 19:33:31.33[ コマンドがそれを真とみなすから。
0055名無しさん@お腹いっぱい。
2013/11/23(土) 19:34:30.39と
[ -f ] && echo hoge
ってことだな。
>>54
なぜ真とみなされるのか、という疑問では。
0056名無しさん@お腹いっぱい。
2013/11/23(土) 19:39:50.36`-n STRING'
`STRING'
True if the length of STRING is nonzero.
0057名無しさん@お腹いっぱい。
2013/11/23(土) 19:39:51.89ということは、真になろうが偽になろうが利用者は文句を言えない。
最初の実装上たまたま真にしたんじゃね?
で、その実装がそのまま引き継がれていると。
以上、想像。
0058名無しさん@お腹いっぱい。
2013/11/23(土) 19:41:30.39あぁ、それが合理的だな
005953
2013/11/23(土) 19:57:40.35$ test hoge
$ echo $?
0
だから
$ test -f
$ echo $?
0
も同じってことですか なるほど
しかし、わかりにくいってか間違いやすいなー
0060名無しさん@お腹いっぱい。
2013/11/23(土) 21:04:08.90ああ、なるほど。鼻から悪魔が出てくるアレと同じ構図なのか。
0061名無しさん@お腹いっぱい。
2013/11/23(土) 22:44:39.50おまえあたまいいな
0062名無しさん@お腹いっぱい。
2013/11/25(月) 08:44:31.22その時、シェルでファイルを定義する必要があるんですが、
AAAAAA=./work/AAAAAA.txt ; export AAAAAA
echo AAAAAA=$AAAAAA
を複数書く必要があるんですが、
AAAAAAを何ヵ所も書き換えるのが大変です
皆さんならどう定義しますか?
0063名無しさん@お腹いっぱい。
2013/11/25(月) 10:14:29.370064名無しさん@お腹いっぱい。
2013/11/25(月) 10:27:09.96もっとわかりやすくて、書きやすい方法ないのかと思い、相談させてもらいました。
現在下のような感じです。
IN1FILEを定義するのに何箇所もIN1FILEとコピペするのが面倒で・・・
Pname=TEST001
echo $Pname START
IN1FILE=${mastpass}IN1FILE.txt ;export IN1FILE
IN2FILE=${mastpass}IN2FILE.txt ;export IN2FILE
OUT1FILE=${mastpass}OUT1FILE.txt ;export OUT1FILE
echo "IN1FILE " $IN1FILE
echo "IN2FILE " $IN2FILE
echo "OUT1FILE " $OUT1FILE
./LINUX/bin/$Pname.bin
ReturnCD=$?
if [ $ReturnCD -eq 0 ] ; then
echo $Pname "NOMAL END (" $ReturnCD ")"
else
echo $Pname "ABNOMAL END !!!!! (" $ReturnCD ")"
exit 1
fi
echo " "
0065名無しさん@お腹いっぱい。
2013/11/25(月) 10:37:44.35bash 前提なら
export IN1FILE=${mastpass}IN1FILE.txt で済む。
0066名無しさん@お腹いっぱい。
2013/11/25(月) 10:40:53.46いまいちshellがわかってなくて・・・
FIL=IN1FILE ; '$FIL=${mastpass}$FIL.txt ;export $FIL ;echo $FIL = $FIL
0067名無しさん@お腹いっぱい。
2013/11/25(月) 10:47:59.240068名無しさん@お腹いっぱい。
2013/11/25(月) 10:51:08.10参考にいろいろやってみてます。
最後の'$'$FILの所がうまく行きませんでした。
FIL=KANFIL ; export $FIL=${mastpass}$FIL.isam ; echo $FIL = '$'$FIL
0069名無しさん@お腹いっぱい。
2013/11/25(月) 10:53:18.96かえってややこしくなりそう。
0070名無しさん@お腹いっぱい。
2013/11/25(月) 10:57:21.15もっといい方法ありますか?
FIL=IN1FILE ; export $FIL=${mastpass}$FIL.txt ; eval echo $FIL = '$'$FIL
汎用機からマイグレをしようと思ってます。
JCLが出力しているような情報は出力させたいので、
echoは必要だと考えています。
0071名無しさん@お腹いっぱい。
2013/11/25(月) 11:02:38.40その場合は、配列にして、
@配列定義
A配列を使ってexport定義
Bプログラム実行
C配列を使ってunsetで解放
って感じが良いのでしょうか
0072名無しさん@お腹いっぱい。
2013/11/25(月) 11:03:54.23> あと、プログラム終わった後、環境変数を解放してあげる必要があるかと思うんですが、
そうなん?
0073名無しさん@お腹いっぱい。
2013/11/25(月) 11:13:38.62汎用機ばっかりだったので、
ファイルを使いたいときは定義、使い終わったら解放ってのが一般的だと思ってたので・・・
次のプログラムでは、定義してないファイルは使えない感じの方がいいのかと思ってますが、
そんな考え方は、必要ないのでしょうか?
0074名無しさん@お腹いっぱい。
2013/11/25(月) 11:42:36.01{
local FIL=$1
eval "$FIL=${mastpass}$FIL.txt ;export $FIL ;echo $FIL = \$$FIL"
}
define_file IN1FILE
define_file IN2FILE
define_file OUT1FILE
環境変数はシェルスクリプトに閉じているからシェルスクリプトが終了すれば消えてなくなる
あとpassってなんだよ。pathの事か?
0075名無しさん@お腹いっぱい。
2013/11/25(月) 11:43:45.620076名無しさん@お腹いっぱい。
2013/11/25(月) 11:56:32.79007864
2013/11/25(月) 12:34:00.24ありがとうございます。
理想的な感じです!!
define_fileを外部ファイル(外部シェル)とする事もできますか?
将来的には、ファイル名、属性、フォルダを渡したいと考えています
define_file IN1FILE mast txt
0079名無しさん@お腹いっぱい。
2013/11/25(月) 13:46:12.01そのシェルの中でevalしないとダメ
別ファイルに記述しといて ドットコマンドで定義を読み込むことは出来る
. define_file.inc
008064
2013/11/25(月) 16:31:39.03論理ファイルと物理ファイルが違う場合が出てきたので、
結局JCLに似た形式にしました。
. ${shelpath}ASCFILE.inc #ファイルアロケート
ASCFILE IN1FILE ${mastpath}IN1FILE.sf
ASCFILE IN2FILE ${tranpath}tran.sf
ASCFILE OUT1FILE ${workpath}OUT1FILE.sf
ASCFILE()
{
local DDNAME=$1 #論理ファイル
local DSNAME=$2 #物理ファイル
export $DDNAME=${DSNAME}
eval echo $DDNAME = '$'$DDNAME
0081名無しさん@お腹いっぱい。
2013/11/26(火) 00:50:42.830082名無しさん@お腹いっぱい。
2013/12/04(水) 13:08:09.83しかし、一部の設定でcshの文法で書かれたファイルをsourceする必要があります。
(cshスクリプトファイルで設定される$pathや環境変数などの設定情報が必要)
shスクリプト内で単純にsourceするとファイルがshで解釈されてエラーになります。
どのようにすれば、shスクリプトでcshスクリプトファイルの設定を引き継げますでしょうか。
shに書き起こすのは無しで、ファイルそのものを使えるのが理想です。
0083名無しさん@お腹いっぱい。
2013/12/04(水) 13:21:02.17cshで読んで、子プロセスとして起動したshに環境変数として渡す。
前処理が必要ならsh→csh→shの入れ子にして動かす。
0084名無しさん@お腹いっぱい。
2013/12/04(水) 14:05:38.910085名無しさん@お腹いっぱい。
2013/12/04(水) 14:14:56.230086名無しさん@お腹いっぱい。
2013/12/04(水) 14:46:50.02変数代入に相当する構文をgrepで抽出して解釈。
ifブロック内での変数操作を拾う点については諦める。
それも嫌ならcshを無理矢理でもいいから突っ込んで動かせ。
0087名無しさん@お腹いっぱい。
2013/12/04(水) 14:50:40.080088名無しさん@お腹いっぱい。
2013/12/04(水) 14:50:48.600089名無しさん@お腹いっぱい。
2013/12/04(水) 22:10:17.840090名無しさん@お腹いっぱい。
2013/12/11(水) 19:06:34.350091名無しさん@お腹いっぱい。
2013/12/11(水) 19:11:03.060092名無しさん@お腹いっぱい。
2013/12/14(土) 05:11:38.010093名無しさん@お腹いっぱい。
2013/12/21(土) 10:57:05.23シェル特集だぞ。
なんか、良いこと書いてる?
0094名無しさん@お腹いっぱい。
2013/12/27(金) 13:24:08.230095名無しさん@お腹いっぱい。
2013/12/27(金) 13:48:23.630096名無しさん@お腹いっぱい。
2013/12/27(金) 14:02:56.75http://developer.android.com/sdk/index.html
0097名無しさん@お腹いっぱい。
2013/12/27(金) 15:10:37.860098名無しさん@お腹いっぱい。
2013/12/27(金) 15:11:17.22付録狙いで買ってくる
0099名無しさん@お腹いっぱい。
2013/12/27(金) 15:17:46.670100名無しさん@お腹いっぱい。
2013/12/27(金) 15:38:28.36ありがとうございます。いま環境がないので姉が帰ってきたら試してみます。
0101名無しさん@お腹いっぱい。
2013/12/27(金) 17:31:10.290102名無しさん@お腹いっぱい。
2013/12/28(土) 13:09:48.31こいつはsshクライアントなんだが、デフォルトだとプロトコルsshって
表示されてるとこでプロトコルlocalを選ぶと、Androidの
一般ユーザー権限でシェルが使えるので。
0103名無しさん@お腹いっぱい。
2013/12/28(土) 13:10:20.830104名無しさん@お腹いっぱい。
2013/12/28(土) 13:22:08.91iOSならネタになるかな?
iOSの公式ストアにあるアプリで、ローカルのシェルが使える奴ってある?
0105名無しさん@お腹いっぱい。
2013/12/28(土) 13:28:06.540106名無しさん@お腹いっぱい。
2013/12/28(土) 13:50:33.34だいぶ厳しい。(grepは入ってる)
でもシェルはkshで行編集やファイル名補完は効くぞ。
なぜかmoreがあるなあと思ったら、これksh組み込みの奴だったのね。
0107名無しさん@お腹いっぱい。
2014/01/11(土) 12:07:28.33それをforループで処理させたい思っており、現在はこんな感じのスクリプト作ってます
OSはCentOS、シェルはbashです
#!/bin/sh
for STR in `4バイトごとに切り取る処理`
do
hogehoge $STR
done
この「4バイトごとに切り取る処理」ですが、現在はsplitで4バイト単位に切り取り、
分割後のファイルを順次読み込ませるということにしているのですが、
分割後のファイルが沢山作られるので遅くなり、またやりたい事の割にやってることが
複雑すぎるので、なんとか改善したいと思ってます
そういうことをしてくれる、いい方法はありますでしょうか
標準出力を、指定したバイト数単位にセパレータを挟んで出力してくれるコマンド、みたいな
cutでやってみようと思ったのですが、これだとオフセットを4バイトずつずらしながら
切り出していく処理となりそうで、これもまた複雑だなぁ、と…
0108名無しさん@お腹いっぱい。
2014/01/11(土) 12:14:05.590109名無しさん@お腹いっぱい。
2014/01/11(土) 12:38:48.750110名無しさん@お腹いっぱい。
2014/01/11(土) 13:01:14.29>>108
なるほどreadでやるのですね
バイト数も任意で変更できそうで、柔軟性もありますね
ありがとうございました
0111名無しさん@お腹いっぱい。
2014/01/11(土) 13:41:30.36つfold
じゃだめなんだっけ?
forをwhileに書き換えるのはおすすめしない。
■ このスレッドは過去ログ倉庫に格納されています