【貝】第1回シェル講座【殻】

このエントリーをはてなブックマークに追加
920名無しさん@お腹いっぱい。:04/07/27 19:12
$cat set.txt
export A="hogehoge"

$cat hoge.sh
#/bin/sh
. ./set.txt
echo "$A"

ってな感じで変数をセットして処理してるんですが、外部ファイルからセットするやり方はコレで正しいですか?
それとも専用のコマンドとかありますか?
あと、set.txtのような設定ファイルの拡張子は慣習的にコレ!ってゆうのはありますか?iniかな?
>>920
私はこんな感じでやってます.
$ cat set.txt
#!/bin/sh
COMMAND='A="hogehoge" '$@
eval $COMMAND
exit $?

$ cat hoge.sh
#!/bin/sh
echo "$A"

$ ./set.txt ./hoge.sh
hogehoge

./configureする前にCFLAGSとかCXXFLAGSとかに最適化フラグを設定したいときなどは,
これでやってます.
ですんで,上記set.txtにあたるファイルの名はexecute_with_flag_optimaizeにしてて,
$ execute_with_flag_optimaize ./configure --prefix hoge
なんてやってます.
>>921
なかなかいいんだけど、evalのところで、""の情報が消えないか?
./set.txt touch "hoge fuga"
とかやったとき
923921:04/07/28 09:32
>>922
そうですね.解決策ないですか?
924922:04/07/28 10:00
こんなかんじで一応できるようだ。

$ cat quote.sh
#!/bin/sh
for i
do
echo -n \"$i\"" "
done

$ cat set.txt
#!/bin/sh
COMMAND='A="hogehoge" '`quote.sh "$@"`
eval $COMMAND
exit $?
925922:04/07/28 10:13
というか
#!/bin/sh
A="hogehoge" "$@"
これでいいじゃん。
926921:04/07/28 10:29
>>925
!なるほど.
しかし私はなんで921みたいにやったんだろう?
927名無しさん@お腹いっぱい。:04/07/31 02:11
変数に文字列を入れたいのですが,その文字列はいろいろなコマンドや awk をパイプで
通ってきたものなんです.
一旦ファイルに入れる以外に,どう書いたら良いのでしょうか.
クォートやエスケープだらけで混乱してしまいます.

emacs のモードがやってくれれば,いくらかマシなんですが...

hoge=`while test -ge 1; do ... ; shift; done | awk '... {...} ...'`
>>927
一行野郎でやりたいわけ?

#ところで'-ge'の左辺はどこに消えた?
つか、具体的にどんな処理をしたいの?
それを書かなきゃ何も判らん罠。
ちゃんと相談する気があるなら、今宵は暇だから付き合ってやってもいいぞ。
>>927
その「いろいろなコマンド」を ` ` の中に書けばいいだけでは。
「いろいろなコマンド」の中で ` ` を使ってるようなら、
最近のシェルの場合は ` ` の変わりに $( ) を使うとネストしやすい。
shiftを使ってるって事は一行野郎ではなさそう。
awk絡みのクオートがややこしいと感じるならawkスクリプトを別ファイルに書いたら?

hoge=`while test $# -ge 1; do ... ; shift; done| ./fuga.awk`
932927:04/08/01 19:14
レスが遅れました.ごめんなさい.
夜遅くでしたので,既に考え方に無理があったのかも知れません.

>>928
ファイルに書いて使うシェルスクリプトです.
「こんな感じ」という意味で書いたのに間違えていましたね.左辺は $# で,
ファイル名です.awk が gnuplot に与えるコマンドの一部を作ります.

それを後でちょっと変えて,最後に gnuplot の set と一緒に gnuplot <<EOF の中に
書こうと思ったのです.

>>929
あぁ...書いた後すぐダウンしました.夜は粘れなくて...

引数に与えたファイルの数だけ
"filename" using 1:2 ,\
"" using 1:3 ,\
を増やそうと思ったのですが,最後のファイルについての 2 行目は
,\ を出力してはいけないんです.
なので,ここは awk でやり,文字列を変数に受け取ろうと思いました.

gnuplot には,グラフの設定にあたる部分と,このプロットをする部分とを
gnuplot <<EOF の中で結合して渡そうとしました.

そこで,どうすればプロットする部分を変数に入れておけるのかな,と思ったのです.
933927:04/08/01 19:21
>>930
こんなのがあるんですか.
bash なのに bourne shell っぽくストイック書いていましたが,
この際 bash をフルに使ってみようと思います.

>>931
あまりファイルを増やしたくないのと,中途半端な機能しかないのを分離すると
ディレクトリが汚れてしまうので...
934名無しさん@お腹いっぱい。:04/08/05 13:59
対話的に現在入力中の一つ前の引数に置換されるのってありましたよね?
なんでしたっけ?

% cp file !$.bak
みたいにやって、file.bak にしたいのですよ。
935934:04/08/05 14:14
使ってるのはzshです。
% cp file !#$.bak
みたいなのでいいのかな。

でも、対話的に使っているのなら zsh では copy-prev-word を使った方が楽なような。
大抵の端末なら Esc-C-/ で OK
937!934:04/08/06 23:46
>>936
おー知らなかった。結構使い道ありそうだね。
938名無しさん@お腹いっぱい。:04/08/07 11:31
bshで環境変数に環境変数名がある時、その環境変数名の値を取り出すにはどうしたらようですか?

AAA="aaa"
BBB="AAA"

のときにBBBからaaaを取得したいんです
>>938
eval echo \$$BBB とか。
つーか、環境変数じゃなくてただの変数では。
940名無しさん@お腹いっぱい。:04/08/07 20:58
>>939
ありがとうございます

で、またまた質問なんですが

====test.sh===========
#!/bin/sh
AAA="aaa"
BBB="AAA"
CCC=`eval echo \$$BBB`
echo "CCC [$CCC]"
===============

$ test.sh
としたばあい

CCC [2256BBB]

となってしまいます
予想では

CCC [aaa]

となつと思ったのにさっぱりわかりません
#!/bin/sh
AAA="aaa"
BBB="AAA"
eval CCC=\$$BBB
echo "CCC [$CCC]"
漏れは aaa command not found とかになるかな,とか思ったのに,
なぜか実行できた.どうして? エロい人!
>>940
` ` の中の \$ が $ に置換され
その後 $$ が PID に置換されてるんでは。
だから
CCC=`eval echo \\\$\$BBB`
とすればいい。
945名無しさん@お腹いっぱい。:04/08/08 15:29
csh使ってるんですが、あるコマンドが";"で区切られた引数を要求するんで

#!/bin/csh
set cmd="/usr/sbin/foo --options='100;200;1;3' -exec"
$cmd

とscriptに書いたのですが、";" が邪魔をして上手く実行できません。
どのように書けば ";" に邪魔されずに $cmd が実行できるんでしょうか?
エスケープしてみろ
動くかどうかは知らんが。
947名無しさん@お腹いっぱい。:04/08/08 21:30
grep "hoge" $file | while read tmp
do
done
echo $tmp

とすると、$tmpの中身が表示されません。
echo $tmp
をdoの中に入れると表示されるんですが、
doの外でも動作させるにはどうすればいいですか?
>>947
そのスクリプトがやりたいことは,
grep "hoge" $file | tail -1
ですよね?

while ...; do ...; done
内の変数を外に出したいとすれば,,,,,,$(...) に入れるとか?
>>947
子プロセスが上がるから、だっけ?
>>947
それ、別プロセス以前に、最後の read が $tmp を空にしてる気がする。

とりあえず、
seq 10 | ( while read tmp; do tmp1=$tmp; done; echo $tmp1 )
みたいにしたら、 tail -1 みたいな動作はしたよ。
951947:04/08/09 08:51
>>948-950
あ、そうか。
whileでEOFを読んじゃってるのか。
そりゃ空になってますね。
ありがとうございました。
他の方法でやってみます。
すみません質問なんですが、
Kshで、片方若しくは両方の変数に2ギガを超える数値を設定して
[[ $inumA -gt $inumB ]]
のような条件式を使うと期待した結果が出ないのですが

対応策のようなものをご存知の方居たらご教授いただきたく。
ちなみにOSはHP-UXです
perlかawk使えと怒られそうですが。

cshでファイルに書かれている内容を1行ずつ処理をしたいのですが、これって
やっぱり無理なんでしょうか?
>>952
ハードのモデルは?
HP-UX のバージョンは?
>>952
確か、桁が多い数値の比較はbcコマンドでやればいいんじゃなかったかな。
956952:04/08/10 22:36
>>954
ハードは多分HPです。
OSは11.00でした。

>>955
シェルでbcコマンドって使ったことがないのですが
自分の例で行くと
[[ `echo $inumA | bc -l ` -gt `echo $inumB | bc -l ` ]]
のような形になるのでしょうか。(-gtは>になる??)
ともあれ早速試してみます。ありがとうございます(ぺこり)
957955:04/08/11 00:06
>>956
確かこう。
A="1234567890999"
B="2234567890999"
if [ "$(echo "${A} < ${B}" | bc)" -eq 1 ]
then
echo ok
fi
958955:04/08/11 19:49
>>956
スマソ。957のはcygwinでは出来たけどHP-UXじゃ出来ないかも。
こんなのはどお?

export A="12345678999999999"
export B="22345678999999999"
if awk 'END{if(ENVIRON["A"]+0 > ENVIRON["B"]+0) exit 1}' /dev/null
then
echo ok
fi
とある環境変数が、
- そもそも定義されていない
- 定義されているけれども、値が「""」(空白文字列)である
を sh で判定する方法を教えてください。

現在は set を使って以下のような醜い方法で判定しています。

#!/bin/sh

isDefined(){
set | grep "^${1}=" > /dev/null && return 0
return 1
}

x=""

isDefined x && echo "x is defined" || echo "x is not defined"
isDefined y && echo "y is defined" || echo "y is not defined"
>>959
printenv
% cat hoge.sh
#!/bin/sh
x=""
echo ${x+"x is defined"}${x-"x is not defined"}
echo ${y+"y is defined"}${y-"y is not defined"}

% sh hoge.sh
x is defined
y is not defined
>>960
以下のように試してみましたが、ヒントから手がかりがつかめません。
もうちょっとヒントください。(-人-)

#!/bin/sh
x=""
printenv $x
echo $?
printenv $y
echo $?

>>961
面白くて参考になります。ありがとうございます。
「定義されているかどうかをチェックする」関数にしたいという希望があったため、
以下のようにしました、、、んが、頭が悪く、スマートな方法が思いつきませぬ。
関数として定義する場合で、もっと頭の良い方法ってあるでしょうか?

#!/bin/sh
isDefined(){
if [ `eval "echo \\${$1+\\"0\\"}\\${$1-\\"1\\"}"` != "1" ]; then
return 0
else
return 1
fi
}

x=""
isDefined x && echo "x is defined" || echo "x is not defined"
isDefined y && echo "y is defined" || echo "y is not defined"
最初に環境変数って言ったから printenv が出てきたんだと思う。
本当に環境変数なら俺も printenv に一票入れるが、
どうもやりたいことは違いそうだな。
>>962
仕様をよく読んでないけど test -z じゃだめなん?
965952:04/08/16 23:55
>>955

返事遅れてすみません。
>>957のほうは今日試してみて稼動確認取れました。
>>958はまだ試してないんですが、今度チャレンジしてみたいと思います。
本当にありがとうございました
966955:04/08/17 00:46
>>965
957のほうで出来ましたか。オレが試したHP-UXだと出来なかった。
最近知ったんだけど、こっちのほうがいいかも。解かり易い。
if expr ${A} '>' ${B} > /dev/null
then
echo ok
fi

bc,awk,expr、桁の制限でいったらどれが一番イケるんだろ?
>>959 は、
環境変数→変数
空白文字列→空文字列
の間違いか。

>>962
961ではないが、こんな感じでいいのかな。

#!/bin/sh

isDefined () {
if eval [ x'${'"$1"'+0}' = x"0" ]; then
return 0
else
return 1
fi
}

x=""
isDefined x && echo "x is defined" || echo "x is not defined"
isDefined y && echo "y is defined" || echo "y is not defined"

zsh だと ${+name} みたいなものもサポートされているようだが。
isDefined(){
eval return \${${1}+0}\${${1}-1}
}
>>968
それだと値が入っているときにおかしくならないか?というわけで、、

isDefined(){
eval \${$1+true} false
}