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

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

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。2007/08/15(水) 07:25:02
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>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 でトレースしましょう。

前スレ
シェルスクリプト総合 その8
http://pc11.2ch.net/test/read.cgi/unix/1171517324/
0787名無しさん@お腹いっぱい。2008/01/26(土) 11:19:04
>>786
じゃあ、date +%s がない Solaris10 は前時代のOSなんだw
0788名無しさん@お腹いっぱい。2008/01/26(土) 12:24:46
>>787
シーラカンスだろ
0789名無しさん@お腹いっぱい。2008/01/26(土) 14:52:38
>>788 は Solaris1.xと混同してる悪寒。
0790名無しさん@お腹いっぱい。2008/01/26(土) 15:07:36
*BSDとlinuxでさえ動けば,他のUNIX使ってる人は自分で勝手になんとかしてくれると思うwww
0791名無しさん@お腹いっぱい。2008/01/26(土) 23:11:38
rm -rコマンドを使用して、「*.txt」以外の
全てのディレクトリ・ファイルを削除したい
http://virus.okwave.jp/qa2500406.html

こいつは馬鹿なの?
http://virus.okwave.jp/user.php3?u=296068

というかなんでこれが良解答なの?
0792名無しさん@お腹いっぱい。2008/01/26(土) 23:26:41
*.txt以外のファイルを取得する部分は
find . ! -name '*.txt'
でいいかな?
0793名無しさん@お腹いっぱい。2008/01/26(土) 23:45:55
そもそも*.txtがあるディレクトリは削除できないので、
> rm -rコマンドを使用して、「*.txt」以外の
> 全てのディレクトリ・ファイルを削除したい
という要求は実現不可能。*.txtを含むディレクトリは除外なら

find . -depth -not -name '*.txt' -a \( -type d -a -empty -o -type f \) -exec rm -rf '{}' ';'
0794名無しさん@お腹いっぱい。2008/01/29(火) 23:10:16
>>791
> というかなんでこれが良解答なの?

一般人しかいないQAサイトじゃそんなもんだろ。
0795名無しさん@お腹いっぱい。2008/01/30(水) 03:01:04
while read のファイル読み込み処理の中で <enter>の入力待ちさせたい時って
みんなどうやってる?
普通に read DUMMY 入れたらバッファである<STDIN>から一行取られて終わり
だよね。
forで回避 or 子shellに分ける以外に俺の行く道はないんすかね?

==== hoge.sh START ================
#!/bin/sh
cat << EOF > ./hoge.list
AAA
BBB
CCC
DDD
EOF

while read i
do
 echo "$i"
 echo "<push enter>"
 read DUMMY
done < ./hoge.list
==== hoge.sh END ======================


ちょっと気になってググったら
ttp://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=34340&forum=10&2
>試しましたが、できましたよ。
とか回答してるやつがいた。

まじすか?
0796名無しさん@お腹いっぱい。2008/01/30(水) 04:29:25
>>795
/dev/ttyを使えばプロセスの制御端末から読める。
read _ </dev/tty

例:
head foo.txt |sh -c 'i=1;while read -r l; do printf "%3d: %s\n" $i "$l";i=$((i + 1)); read _ </dev/tty; done'
0797名無しさん@お腹いっぱい。2008/01/30(水) 05:04:54
>>795
>>796 の方が素直だが、別の fd を用意する方法もある。
例えば、ファイルを fd3 から読むのなら、こんなかんじ。

exec 3< "./hoge.list "
while read i 0<&3
do
 echo "$i"
 echo "<push enter>"
 read DUMMY
done
07987952008/01/30(水) 09:17:51
>>796 >>797
おおー その手がありましたか。
ありがとうございます。
0799名無しさん@お腹いっぱい。2008/02/01(金) 21:46:35
別段困っているわけではないのですが、

~/.forwardをバックアップするスクリプトを書いてたのですが、

最初これでいいかなと思ったのですが、
cd /home; tar cvf /tmp/tmp.tar */.forward

よく考えたらユーザ数が非常に多い環境ではエラーになります。
それで試行錯誤して、こうしたのですが、

( cd /home ; find . -name .forward -maxdepth 2 -print | tar cvf /tmp/tmp.tar -T - )

エレガントではない。もっと綺麗な書き方はないですかね。
0800名無しさん@お腹いっぱい。2008/02/01(金) 21:48:51
補足。 -maxdepth を指定しているのは、各ユーザの
ホーム直下以外に .forward というファイルがあるから
です。
0801名無しさん@お腹いっぱい。2008/02/01(金) 21:55:29
それで充分だと思うが.
というかエレガントでないとも思わないが.
0802名無しさん@お腹いっぱい。2008/02/01(金) 21:58:01
find の -maxdepth と、tar の -T がポータブルじゃないのがノンエレガントだな。
08037992008/02/01(金) 23:22:55
>>801
コマンドの長さが2倍になったのが気に入らなかったのです。

>>802
そこまで気が回らなかった。
0804名無しさん@お腹いっぱい。2008/02/01(金) 23:41:07
気が回らなかったっていうより気にする必要がなかったんじゃないの。
状況限定だろうし。あえていうなら-Tよりは-Iの方がポータブル?
08057992008/02/01(金) 23:53:10
>>804 気にする必要がなかったんじゃないの

いやま、それを言うなら、うちはユーザ数が400名程度だから、
事実上、これでも全く問題ないわけなんです。

cd /home; tar cvf /tmp/tmp.tar */.forward

shellの引数の最大値は幾つぐらいだったか忘れたけど、数千のオーダーだろうし。
0806名無しさん@お腹いっぱい。2008/02/02(土) 00:18:03
cpio使え。
0807名無しさん@お腹いっぱい。2008/02/02(土) 07:19:21
質問です。
以下のように変数にスペースを含む文字列(ファイル名)を入れ、それを
別の変数の定義に使おうとしています。

FILE="foo bar.txt"
FLAGS="-l $FILE"
ls $FLAGS

しかしこれだとうまくいきません。

foo: No such file or directory
bar.txt: No such file or directory

ほかに FLAGS="-l \"$FILE\"" とか ls "$FLAGS" とか試しましたが
間違いでした。
どう書けばいいのでしょう?
0808名無しさん@お腹いっぱい。2008/02/02(土) 07:41:41
>>807
FLAGS="-l '$FILE'"

だけどその例だと
FLAGS="-l"
ls $FLAGS "$FILE"
の方が適当なんじゃないの。

別解としては
FLAGS='-l "$FILE"'
eval ls $FLAGS
0809名無しさん@お腹いっぱい。2008/02/02(土) 08:29:20
>>807
>しかしこれだとうまくいきません。
これはこれで、うまくいってるよ。
No such file or directory(そんなファイルやディレクトリはないよ)
と言われてるんだから、単にカレントディレクトリに foo と bar.txt が無いだけだよ。

正しくは >>808 の言う通りだと思う。
0810名無しさん@お腹いっぱい。2008/02/02(土) 10:19:27
FILE="foo bat.txt"
set -- -l
set ${1+"$@"} "$FILE"

ls ${1+"$@"}
0811名無しさん@お腹いっぱい。2008/02/02(土) 10:44:29
>>810
明らかに1つ以上 setしてるんだから、${1+"$@"} なんて書き方する必要なし。
"$@" だけでOK。

あと、引数が0の場合であっても現行のシェルなら "$@" ですべてOK。
${1+"$@"} という書き方はもう古いので、そろそろ撲滅すべし。
0812名無しさん@お腹いっぱい。2008/02/02(土) 11:12:57
これ
set -- -l
と、これ
FILE="foo bat.txt"
と、これ
set ${1+"$@"} "$FILE"
ls ${1+"$@"}
が、別々のモジュールになるかも知れないので、安全な方に倒すのが当然だね。
お前のプログラムってバグだらけだろう。

> ${1+"$@"} という書き方はもう古いので、そろそろ撲滅すべし。
Solaris10ではまだ必要。
0813名無しさん@お腹いっぱい。2008/02/02(土) 11:34:33
>>812
>Solaris10ではまだ必要。

嘘書くな。Solaris10上で、$# = 0 の状態で "$@" が問題なく消えてくれる
(空文字列が残らない)ことは確認済み。

${1+"$@"}が必要なようなシェルは今は残っていない。
0814名無しさん@お腹いっぱい。2008/02/02(土) 11:50:01
>>813
条件はSolaris10じゃなかった。
set -uされている状態で使われる可能性がある場合。
0815名無しさん@お腹いっぱい。2008/02/02(土) 12:04:03
>>814
言うと思った。set -u の話なんて誰もしてない。後出し乙

結論: ${1+"$@"} は不要
0816名無しさん@お腹いっぱい。2008/02/02(土) 12:06:40
> 言うと思った。set -u の話なんて誰もしてない。後出し乙
これを後出しと言わずして、何を後出しといおうか… 大笑い。
0817名無しさん@お腹いっぱい。2008/02/02(土) 12:13:13
むしろ、Solaris で set -u の時 "$@" がおかしくなるのは
Solarisのバグだと思うぞ。

そもそも set -u なんてすることは滅多にないし、そういう意味でも "$@" 推奨。
0818名無しさん@お腹いっぱい。2008/02/02(土) 12:21:52
元の質問は >>807 なわけだ。
そこには、
引数が0個の場合とか、
シェルスクリプトが別ファイルにわかれる場合とか、
set -uする場合とか、
一切書いていない。

勝手な条件を後出しで付け加えたのは >>810

さらに言うと、>>810 の方法では位置パラメータが破壊されるから
そもそも setを使うのは効果的じゃない。そんなことしなくてもできるし。
0819名無しさん@お腹いっぱい。2008/02/02(土) 12:38:45
>>817
ashでも
@: parameter not set
という警告がでるが。
> そもそも set -u なんてすることは滅多にないし、そういう意味でも "$@" 推奨。
お前perlでuse strictしないの? ダメな奴だな。

>>818
後出しでケチつけていくのがみっともない。しかも致命的な欠陥の指摘じゃないから反論される。

> さらに言うと、>>810 の方法では位置パラメータが破壊されるから
破壊されても問題ない場合や、シェルファンクションで使える。

> そもそも setを使うのは効果的じゃない。
根拠なし。

> そんなことしなくてもできるし。
別解という言葉を調べてみることをお勧めする。
0820名無しさん@お腹いっぱい。2008/02/02(土) 12:44:48
>>819
$ ash
$ set -u
$ echo $#
0
$ echo "$@"

$

問題なしw
0821名無しさん@お腹いっぱい。2008/02/02(土) 12:54:11
$ uname -a
FreeBSD orz 8.0-CURRENT FreeBSD 8.0-CURRENT #1: Tue Jan 29 01:35:03 JST 2008 root@:/usr/obj/src/sys/orz i386

$ sh
$ set -u
$ echo $#
0
$ echo "$@"
@: parameter not set

実例が提示されたので、以下は嘘。
> ${1+"$@"}が必要なようなシェルは今は残っていない。
0822名無しさん@お腹いっぱい。2008/02/02(土) 12:59:31
>>821
だから、set -u の話は後出し

> ${1+"$@"}が必要なようなシェルは今は残っていない。

のは、"$@" が "" (空文字列) に展開されるような古いシェルのこと。

よって、
> ${1+"$@"}が必要なようなシェルは今は残っていない。
は、正しい。
0823名無しさん@お腹いっぱい。2008/02/02(土) 13:06:51
> のは、"$@" が "" (空文字列) に展開されるような古いシェルのこと。
ハイハイ、後出し。wwww

> ${1+"$@"}が必要なようなシェルは今は残っていない。
これは嘘。
0824名無しさん@お腹いっぱい。2008/02/02(土) 13:14:38
>>812 では、
${1+"$@"}が必要な理由として、

set -- -l と FILE="foo bat.txt" と、set ${1+"$@"} が
別々のモジュールになるかも知れないので、

と言っている。
これは、引数が0個になる場合があるから、と言う意味に他ならない。

それに対する反論として、
>>813 で、${1+"$@"} は不要と言っている。

その「後」で、>>814 が set -u の話を持ち出している。

よって、>>814 の set -u が後出し。

あと、未だに set -u で "$@" がエラーになる FreeBSDもバグ持ちと言うことだな。
0825名無しさん@お腹いっぱい。2008/02/02(土) 13:20:24
>>807が前提条件全部出さないのが悪い。
0826名無しさん@お腹いっぱい。2008/02/02(土) 13:27:40
・set -- -l と FILE="foo bat.txt" と、set ${1+"$@"} が別モジュールになる。
・set -uで警告が出る(ので回避する)
は排他じゃない。

>>811は、${1+"$@"}を空文字列への展開を避けるためと思い込んで、突っ込み(>>811)を
入れたのはいいが、set -uでの警告を知らなかったため、しどろもどろで反論を続けている。
かなり見苦しいぞ。www

> あと、未だに set -u で "$@" がエラーになる FreeBSDもバグ持ちと言うことだな。
FreeBSDだけじゃなく、Solaris10でも同じように警告が出るぞ。

ところで、お前が試したashって何処のashだよ。
ash -> bashじゃねーのか? www
0827名無しさん@お腹いっぱい。2008/02/02(土) 14:21:04
ちょっとここまでの流れを誰かわかりやすく説明してくれwwww
0828名無しさん@お腹いっぱい。2008/02/02(土) 14:42:22
>>810 位置パラメータを用いた別解をだす。
>>811 ${1+"$@"}という記法に因縁つける。
>>810 反論のついでに「お前のプログラムってバグだらけだろう。」と煽る。>>812
>>811 必死の再反論を試みるが迎撃され、逃亡。 <<=== 今ココ
0829名無しさん@お腹いっぱい。2008/02/02(土) 15:06:57
${1+"$@"}の意味がわからない俺は間違いなくゆとりlinux使い\(^o^)/
0830名無しさん@お腹いっぱい。2008/02/02(土) 15:35:02
ウチの社内標準では、「${1+"$@"}は過剰品質。簡潔な記述として"$@"を使うこと」
となってる。実際、ラッパーの類とか、皆 "$@"で書かれてるよ。
0831名無しさん@お腹いっぱい。2008/02/02(土) 16:04:20
>>810 位置パラメータを用いた別解をだす。
>>811 ${1+"$@"}という記法に因縁つける。
>>810 反論のついでに「お前のプログラムってバグだらけだろう。」と煽る。>>812
>>811 必死の再反論を試みるが迎撃され、逃亡。
>>811 噴飯物の社内標準を持ち出す。 <<=== 今ココ
0832名無しさん@お腹いっぱい。2008/02/02(土) 16:09:10
set -u が問題なら、

set +u
hoge "$@"

って記述すれば委員じゃないの? 何がそんなに問題なの?
0833名無しさん@お腹いっぱい。2008/02/02(土) 16:09:49
で,どっちのほうが正しいんだ?
ポータビリティと簡潔さのトレードオフだとは思うんだけど.
0834名無しさん@お腹いっぱい。2008/02/02(土) 16:14:45
FreeBSDの /bin/shの件は send-pr よろしこ。
0835名無しさん@お腹いっぱい。2008/02/02(土) 16:23:08
仕様というか、文法的には、$@ は、0個の場合も含む位置パラメータに展開される
特殊パラメータとして定義されている。
この定義は、たとえ位置パラメータの個数が0個の場合でも変わらない
(=未定義にはならない)ので、
$@は、位置パラメータの個数が0個の場合でも定義されていると考えられる。
よって、set -u 状態での $@ の参照を、
「未定義パラメータの参照」とみなしてしまう一部のシェルの実装は
バグと考えて良い。
0836名無しさん@お腹いっぱい。2008/02/02(土) 16:25:45
>>832
冗長な記述を否定するために、より冗長な記述を持ってきても説得力ないぞ。
しかも戻すために処理後にset -u必要だし。
いや、nounsetが設定されていることを確認しないといかんな。

if set -o | egrep 'nounset *on' >/dev/null 2>&1; then
set +u
hoge "$@"
set -u
else
hoge "$@"
fi
こうか? www

>>833
噴飯物の社内標準がなければ${1+"$@"}と書いても5文字増えるだけだ。

>>834
お前がやれ。理由は「社内標準が守れないから」とでもしとけ。www
0837名無しさん@お腹いっぱい。2008/02/02(土) 16:33:04
$@ に限らず、$# $! $? などの「特殊」パラメータはすべて unsetできない。
unsetできるのはシェル変数だけ。
それとは別に、「位置」パラーメータは未設定の場合もあり得る。

そして、$@は、「位置」パラーメータではなく
「特殊(←ここ重要)」パラメータであるということ。

set -u はそもそもシェル変数や「位置」パラーメータのように、
未設定である場合があり得るパラメータに対してチェックするためのもの。
その set -u が、「特殊」パラメータである $@ に反応してしまうのはおかしい。
0838名無しさん@お腹いっぱい。2008/02/02(土) 16:35:51
>>837
いや、その説明だと、特殊パラメータの $! は、バックグラウンド起動歴が
なければ未設定になるから、説明にならない。

>>835 の説明の方が正しいんじゃないか?
0839名無しさん@お腹いっぱい。2008/02/02(土) 16:39:38
うん、じゃあ。その説を世界中のシェル開発者に納得させて全部修正させてから。
↓こう主張してね。
> あと、引数が0の場合であっても現行のシェルなら "$@" ですべてOK。
> ${1+"$@"} という書き方はもう古いので、そろそろ撲滅すべし。
0840名無しさん@お腹いっぱい。2008/02/03(日) 04:03:25
${1+"$@"} としなくても済む環境ならそれでいいだろうけど
ウチでは set -u 必須としてて環境的に ${1+"$@"} せざるを得ないんで

> 結論: ${1+"$@"} は不要

と言われても全然結論じゃないんだけどな "$@"にしたら問題起きるんで書き直しだし

まぁ言語仕様的には "$@" で問題起きない方が正しいのかもしれんが
シェル開発者や仕様企画者の集まりっていうならともかく
元々伝統的な方法でもあるんで必死こいて ${1+"$@"} を否定する意味が分からない
0841名無しさん@お腹いっぱい。2008/02/03(日) 07:40:37
>>840
set -u 必須ってどんな環境?

俺の認識では、set -u はあくまでデバッグ用であって、
本番スクリプトでset -uを記述するなんてあり得ないんだけどな。

で、set -u必須だったとして、例えば、あるオプション変数がセットされてれば
使うけど、セットされてなければ黙って無視したいような場合、

hoge_command $HOGE_OPT

って書いちゃ駄目なんだよね? (不便だな)
いちいち
hoge ${HOGE_OPT+HOGE_OPT}

って書くのかなw
0842名無しさん@お腹いっぱい。2008/02/03(日) 08:20:12
>>841
hoge ${HOGE_OPT+HOGE_OPT}
わらた
タイプミスで初期化してない変数を見てしまうバグが未然に防げる可能性があるだろ
0843名無しさん@お腹いっぱい。2008/02/03(日) 08:42:59
>>842
つねに ${HOGE_OPT+$HOGE_OPT} って書かなければならないルールになっちゃうから、

${HOGE_OPT+$HOGE_ORT} っていうタイプミスすると防げない。
0844名無しさん@お腹いっぱい。2008/02/03(日) 08:58:04
>843 中身がないときはifでよけて書けばいいんじゃね?
0845名無しさん@お腹いっぱい。2008/02/03(日) 08:59:22
>>844
中身がないかどうかを set -u の状態で ifで判定ってできる?
0846名無しさん@お腹いっぱい。2008/02/03(日) 09:09:30
空文字列か何かで初期化?
0847名無しさん@お腹いっぱい。2008/02/03(日) 09:16:38
>>846
シェルスクリプト内部で定義する変数なら最初空文字列で初期化でいいけど、
起動時に環境変数で渡される変数だと、
結局セットされてるかどうかの判定が必要になるからあまり意味ないね
0848名無しさん@お腹いっぱい。2008/02/03(日) 09:25:25
set -u 環境では、
if [ -n "$HOGE" ]; then
みたいなよくやる書き方もできないわけだ。

いちいち
if [ -n "${HOGE+$HOGE}" ]; then
って書くのかな?

あるいは最初にいちいち
: ${HOGE=}
とかするのかな。いずれにしても不便だなw
0849名無しさん@お腹いっぱい。2008/02/03(日) 09:30:58
>>848
[ -n "${HOGE+$HOGE}" ]
なんてしなくても、
[ -n "${HOGE-}" ]
で十分。

ところが、いつも${HOGE-}する癖がつくと結局 set -u の意味がなくなる。

rm -i をaliasしても無意味なのと似てる。
0850名無しさん@お腹いっぱい。2008/02/03(日) 09:46:07
>>829
俺は意味は分かるし、見かけたこともあるが、
なぜそんな冗長な書き方をしていたのかは
今の流れで初めて分かった。

で、set -u のバグがあるのは FreeBSD だけ?
0851名無しさん@お腹いっぱい。2008/02/03(日) 11:13:41
>>849

素人さんにプロのテクニックを教えてやろう。
set -uはタイプミスを検出するために使うんだよ。全ての変数は明示的に初期化する。
従って未定義の変数はタイプミスだ。
0852名無しさん@お腹いっぱい。2008/02/03(日) 11:49:24
>>851
なるほど。
一つ賢くなった気がする。
0853名無しさん@お腹いっぱい。2008/02/03(日) 11:55:26
>>851
その説明だと、未定義の場合もアリのスクリプトが書けない。
変数を他から引き継ぐ場合、初期化するわけにもいかない。
定義済みかどうかの判定がどこかで必要になる。
で、定義済みかどうかの判定自体が set -u に引っかかるから、
>>849 が指摘してるように冗長な記述が必要になる。
そこまで代償を払って set -u する必要もなかろう。
0854名無しさん@お腹いっぱい。2008/02/03(日) 12:09:06
>>853
> 変数を他から引き継ぐ場合、初期化するわけにもいかない。
> で、定義済みかどうかの判定自体が set -u に引っかかるから、
未定義ならば代入という記法があるので問題ない。(何度も出ているが${parameter=word})
いい加減に負け認めて引っ込みなよ。見苦しい。

>>810 位置パラメータを用いた別解をだす。
>>811 ${1+"$@"}という記法に因縁つける。
>>810 反論のついでに「お前のプログラムってバグだらけだろう。」と煽る。>>812
>>811 必死の再反論を試みるが迎撃され、逃亡。
>>811 噴飯物の社内標準を持ち出すも撃破される。
>>811 ムキになって反論するも、無知をさらけ出す結果に陥る。 <=== 今ココ
0855名無しさん@お腹いっぱい。2008/02/03(日) 12:10:30
>>854
>未定義ならば代入という記法があるので問題ない。

だから、その記述が冗長といってるんじゃないかw
0856名無しさん@お腹いっぱい。2008/02/03(日) 12:16:23
>>855
全ての変数は初期化するといってるだろ。
これが冗長だというならperlでも冗長だからuse strictしてないんだろうな。
「お前のプログラムってバグだらけだろう。」 www
0857名無しさん@お腹いっぱい。2008/02/03(日) 12:17:16
宗教論争の様相を呈してまいりました.
つうわけでアンケート.

変数は使うときまで宣言しない派?最初に宣言しとく派?
0858名無しさん@お腹いっぱい。2008/02/03(日) 12:20:39
シェルスクリプトは、あらかじめ変数宣言しないでも
その場ですぐ使えるのがメリットだろ。
堅苦しく変数宣言必須にするならメリット半減だな。
0859名無しさん@お腹いっぱい。2008/02/03(日) 12:21:08
そのアンケートは的外れ。
0860名無しさん@お腹いっぱい。2008/02/03(日) 12:28:27
シェルスクリプトで変数宣言するのは
関数のローカル変数を設定する時ぐらいだな。
0861名無しさん@お腹いっぱい。2008/02/03(日) 12:28:45
set -u 派の人って、#!/bin/sh -u で記述してるの?
それとも本文に set -u 入れてるの?
あまり見かけないけど
0862名無しさん@お腹いっぱい。2008/02/03(日) 12:33:57
>>858
キミのしょぼいスクリプトを基準に語られても困る。
0863名無しさん@お腹いっぱい。2008/02/03(日) 12:36:43
例外?何それみたいな使い捨てスクリプトも書けるし
ずっと使っていくようなものも書ける
その幅の広さがシェルスクリプトのいいところじゃね?
0864名無しさん@お腹いっぱい。2008/02/03(日) 13:47:22
横槍だが、そもそも${1+"$@"}がどういう意味なのか
わからないから、なぜそう書くのか理解できない。
0865名無しさん@お腹いっぱい。2008/02/03(日) 13:57:57
${parameter+word}という記法はparameterがセットされている場合はwordに展開される。
なので、${1+"$@"}は位置パラメーター$1がセットされていると"$@"に展開される。
08668642008/02/03(日) 14:51:45
>>865
ありがとう。manには:+しかなかったから別物だと思った。
見なおしたら"If the colon ( :) is omitted〜"って文があった。
www.cs.princeton.edu/~jlk/kornshell/doc/man88.html
0867名無しさん@お腹いっぱい。2008/02/04(月) 21:43:38
>>811 ほら調べてやったぞ。SUSE 9, Redhat 4, Solaris10, Service for UNIX 3.5
警告でないのはRedhat 4のashだけだ。FreeBSD 8も合わせてバグ報告しとけ。www
★SUSE LINUX Enterprise Server 9 (x86_64) p3
$ /bin/ash -cu 'echo "$@"'
/bin/ash: @: parameter not set
$ /bin/ksh -cu 'echo "$@"'
/bin/ksh: @: parameter not set
★Redhat 4 u5
$ /bin/ash -cu 'echo "$@"'

$ /bin/ksh -cu 'echo "$@"'
/bin/ksh: @: parameter not set
★Solaris10 8/07
$ /bin/sh -cu 'echo "$@"'
/bin/sh: @: parameter not set
$ /bin/ksh -cu 'echo "$@"'
/bin/ksh: @: parameter not set
$ /usr/xpg4/bin/sh -cu 'echo "$@"'
/usr/xpg4/bin/sh: @: parameter not set
★SFU(Service for UNIX) 3.5
$ /bin/sh -cu 'echo "$@"'
/bin/sh: @: parameter not set
$ /bin/ksh -cu 'echo "$@"'
/bin/ksh: @: parameter not set
0868名無しさん@お腹いっぱい。2008/02/04(月) 21:46:31
>>867
もはやこれは愛だな
0869名無しさん@お腹いっぱい。2008/02/04(月) 22:03:43
Kシェルスクリプトについての質問です。

file1に入っている文字を、file2の中で検索し、あればエラーなしという
スクリプトを書きたいのですが、どなたかご教授願えないでしょうか?

file1には以下のような文字が200行程度、入っています。
aaa 12345678
bbb 12345678
ccc 12345678

file2には以下のような文字が300行程度入っております。
aaa 09876543
bbb 09876543
ccc 09876543
ddd 09876543

このfile1に入っている頭3文字の行全てを、file2の頭3文字にあるかないか、
といったスクリプトを書きたいのですが、シェルの基本程度しかしらず
悪戦苦闘をしております。なにとぞ、ご教授願いますよう、お願いします。
0870名無しさん@お腹いっぱい。2008/02/04(月) 22:11:16
>>869
kshじゃなくても、普通のshで書けるね。


#!/bin/sh

while read key other
do
if grep -q $key file2; then
echo "$key は file2にある"
else
echo "$key は file2にない"
fi
done < file1
08718692008/02/04(月) 22:16:58
Kシェルが社内標準になっちゃったんです…
さらに運悪くジョブ管理までやらされるはめに。
ご迷惑をおかけしますが、何卒よろしくお願いします
0872名無しさん@お腹いっぱい。2008/02/04(月) 22:17:48
kshは下位互換性ないの?
0873名無しさん@お腹いっぱい。2008/02/04(月) 22:18:56
>>871
だったら #!/bin/ksh って書けばいいだけだよ。

あと、grep -q $key は grep -q "^$key" の方がいいかな。
0874名無しさん@お腹いっぱい。2008/02/04(月) 22:19:52
shでできることは、ほぼそのまま変更せずにkshでもできる。
08758692008/02/04(月) 22:20:57
>>872
あるんですが、今後はKシェルで書けとの命令が上から下りまして…
0876名無しさん@お腹いっぱい。2008/02/04(月) 22:24:19
>>875
こいつ、ネタか?
この場合、kshで書いても shと全く同じものになるんだよ。

それとも、何か最低限 ksh専用の文法を使わなけりゃいかんのかよ?
08778692008/02/04(月) 22:32:56
皆様、ありがとうございます。
丁寧に答えてくださり、まことに感謝しております。

>>876
何分Kshの事を全然知らなくて…
Goto文が書けないやら、色々戸惑っている最中です。
もし何かまたわからない事がありましたら、ご質問させていただきます。

今回は本当にありがとうございました。
0878名無しさん@お腹いっぱい。2008/02/04(月) 22:41:33
横レスで便乗質問です。
偶然ですが、>>870 と同じようなスクリプトを書くために悪銭苦闘しています。
とりあえず /bin/shでではできたんですが、
今後はbashシェルで書けとの命令が上から下りまして…
>>870 をbashシェルで書くとどのようになりますでしょうか、ご教授ください。
なお、#!/bin/shを#!/bin/bashに変えただけでは却下され、
何か最低限bashシェル専用の文法を使わなければ上司が納得してくれません。
0879名無しさん@お腹いっぱい。2008/02/04(月) 23:26:50
あっそ
0880名無しさん@お腹いっぱい。2008/02/04(月) 23:44:18
>>878
なぜsh互換ではNGでbash専用でないとダメなのか
その上司を問いつめて、結果をこのスレに書き込んでみ?
0881名無しさん@お腹いっぱい。2008/02/05(火) 00:49:39
おれのエスパー予想では、話題を変えようとしている>>811の涙目自演。
0882名無しさん@お腹いっぱい。2008/02/05(火) 02:11:40
>>878
まず
ttp://search.luky.org/linux-users.9/msg06102.html
とか嫁
0883名無しさん@お腹いっぱい。2008/02/05(火) 02:30:35
>>878
test とか [ を [[ 記法にでも変えたら?
0884名無しさん@お腹いっぱい。2008/02/05(火) 03:10:05
ttp://www.nicovideo.jp/watch/sm2217336
うっう〜
0885名無しさん@お腹いっぱい。2008/02/05(火) 07:15:24
>>883
testも[もないんだが、>>870 には。
0886名無しさん@お腹いっぱい。2008/02/05(火) 09:47:50
その気になればいくらでも変態的記法で書き換えられるぞ。w
こんなの趣味でも書かないけどな。w

#!/bin/bash

while read line
do
 grep "${line:0:3}" file2 &> /dev/null
 if $[ $? == 0 ] ; then
  echo "$key は file2にある"
 else
  echo "$key は file2にない"
 fi
done <<< "$( < file1 )"
0887名無しさん@お腹いっぱい。2008/02/05(火) 09:49:48
あ、間違えた。
けど、こんなの使わないからいいか。w
■ このスレッドは過去ログ倉庫に格納されています