[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 2chのread.cgiへ]
Update time : 02/10 13:03 / Filesize : 248 KB / Number-of Response : 977
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

シェルスクリプト相談室



1 名前:デフォルトの名無しさん [2005/04/04(月) 03:43:03 ]
シェルスクリプトに関する質問・回答や議論等を行う相談室スレッド。 


267 名前:デフォルトの名無しさん [2006/05/30(火) 23:30:23 ]
質問です。Solaris9で、

rsh 192.168.1.1 su - user -c "ls -l"

みたいな事やりたいんですけど、
"ls -l"のオプション部分が有効になりません。
なんとかならないでしょうか?

268 名前:デフォルトの名無しさん mailto:sage [2006/05/31(水) 03:19:58 ]
>>267
リモートで実行するコマンドをまとめて括れ

rsh 192.168.1.1 'su - user -c "ls -l"'


269 名前:デフォルトの名無しさん [2006/05/31(水) 11:10:05 ]
初歩的ですみませんがファイルのreadで質問があります
以下のreadの仕方では最終行にリターンコードがないと
最終行を読んでくれません。※リターンコードがあればreadしてくれますが・・・。
読む方法はないでしょうか

cat /aaa.txt | while read FILE
do
echo $FILE
done

aaa.txtの内容(この例だとghiを読み込まない)
abc
def
ghi

270 名前:デフォルトの名無しさん mailto:sage [2006/05/31(水) 11:43:23 ]
>>269
catじゃなくて、必ず改行するタイプのフィルターに通せばいい。
例えば、awk '{print;}'でもいける。

271 名前:デフォルトの名無しさん [2006/06/09(金) 13:30:25 ]
〜日前のファイルを削除するようなスクリプトを作成したいのですが
どのような感じになりますか?

272 名前:デフォルトの名無しさん mailto:sage [2006/06/09(金) 13:34:39 ]
>>271
findではいけない理由があるのかね。
取り敢えず、1日(24時間)以上前のファイルを無条件に削除するならこんな感じ。
find . -mtime +1 -exec rm {} \;


273 名前:デフォルトの名無しさん mailto:sage [2006/06/09(金) 14:18:24 ]
ctimeじゃないのか

274 名前:デフォルトの名無しさん [2006/06/09(金) 23:03:08 ]
>>269
それ、最後の行まで普通にでたんだが、OSによるもんなのか
当方HP

275 名前:デフォルトの名無しさん mailto:sage [2006/06/10(土) 08:59:55 ]
何となく本末転倒な対処

perl -wne 'chomp;print $_."\n";' ./aaa.txt | while read FILE
do
echo $FILE
done



276 名前:デフォルトの名無しさん mailto:sage [2006/06/12(月) 17:01:03 ]
こんな感じかなあ。(以下は Linux でシェルは bash 3.00.16 使ってます)。

$ perl -e 'print "abc\ndef\nghi"' >a
$ od -c a
0000000 a b c \n d e f \n g h i
0000013
$ cat a | while read s ; do echo "* $s" ; done
* abc
* def
$ ( cat a ; echo '' ) | while read s ; do echo "* $s" ; done
* abc
* def
* ghi
$ awk 1 a | while read s ; do echo "* $s" ; done
* abc
* def
* ghi
$


277 名前:デフォルトの名無しさん [2006/06/13(火) 11:26:53 ]
>>272
数日前のファイルは無条件に削除という認識ではあってるのですが
ディレクトリの指定をする場合にはどのようになりますか?

278 名前:デフォルトの名無しさん mailto:sage [2006/06/13(火) 12:03:13 ]
>>277
man で調べりゃいいじゃないか。


279 名前:272:'.'はカレントディレクトリとその配下 mailto:sage [2006/06/13(火) 12:12:52 ]
>>277
取り敢えずディレクトリ指定しているんだけどなぁ。

280 名前:デフォルトの名無しさん [2006/06/13(火) 13:19:34 ]
>>279
例えば、フォルダを指定した場合(/tmp)
find /tmp -mtime +1 -exec rm {} \;
上記で/tmpディレクトリ以下の1日以上経過したファイルの削除が行われる
と思って、よろしいのでしょうか?

281 名前:デフォルトの名無しさん mailto:sage [2006/06/13(火) 14:05:59 ]
ttp://www.google.com/search?hl=ja&q=manpage+of+find&lr=lang_ja

282 名前:デフォルトの名無しさん [2006/06/13(火) 14:19:50 ]
「(::´┏┓`:)なんでそんなに英語を使ってやんのが好きなの?」

283 名前:デフォルトの名無しさん mailto:sage [2006/06/13(火) 14:52:23 ]
>>280
何が消されるのか不安なら -exec から後ろをなくしてみればいい。


284 名前:デフォルトの名無しさん mailto:sage [2006/06/13(火) 16:54:29 ]
>>280
どうして、マニュアル見て自分で確認せずに聞いて済まそうとするかねえ。
嘘教えられて、重要なファイル消すはめに陥ったらどうするんだよ。

285 名前:デフォルトの名無しさん mailto:sage [2006/06/14(水) 16:04:58 ]
初歩的なことを一つ教えてください。

bshで関数定義したものを別のシェルで呼び出すことは出来ますか?
出来るとすると呼び出し方はどのようになりますでしょうか。



286 名前:デフォルトの名無しさん mailto:sage [2006/06/14(水) 17:02:26 ]
できます。
関数が入ったファイルfoo.shをbar.shの中で使いたければ、bar.shの中で
. ./foo.sh
などとすれば普通に呼べます。

287 名前:デフォルトの名無しさん mailto:sage [2006/06/14(水) 17:06:41 ]
なんだ別のシェルって、そういう意味か。

シ ェ ル ス ク リ プ ト っ て 書 け よ。


288 名前:デフォルトの名無しさん mailto:sage [2006/06/14(水) 21:09:56 ]
bshスクリプトを/bin/sh以外のシェル、たとえばcshから呼べますか?だったら
「呼べない」が答えですな。というか、そういう質問なのか?

289 名前:285 mailto:sage [2006/06/15(木) 00:14:48 ]
bshで書かれたシェルスクリプト内の関数を、
別のbshで書かれたシェルスクリプトで使用することはできますか?

ということで・・・(´・ω・`)

290 名前:デフォルトの名無しさん mailto:sage [2006/06/23(金) 14:19:28 ]
while文で一つのリストファイルから呼び出しをかけて、ループさせることは
可能だと思うのですが同じwhile文中で違うリストファイルから呼び出しをかけて
変数として扱うことは可能でしょうか?

291 名前:デフォルトの名無しさん mailto:sage [2006/06/24(土) 01:05:24 ]
リストファイルって?
呼び出しって?
かけるって?


292 名前:デフォルトの名無しさん mailto:sage [2006/06/24(土) 13:18:35 ]
>>290の要求がどうなのかは知らんけど、俺も心当たりある。

... | while read var; do ...; done
っていうパターンあるじゃんか。そうじゃなくて
while [ ... ]
do
if [ ... ]; then read var1 ただしファイルディスクリプタ1(パイプやファイル)から;
else read var2 ただしファイルディスクリプタ2(別なパイプやファイル)から;
fi
done
のようなことをやりたいと思うことはあったわ。

俺はexecによるディスクリプタコピーととサブシェルプロセスを組み合わせて
やろうとして挫折して、perlに日和った。

293 名前:デフォルトの名無しさん [2006/06/25(日) 02:48:36 ]
sudo等でパスワードを求めるプロンプトに
expect以外で自動入力する方法はありますか?


294 名前:271 mailto:sage [2006/07/03(月) 10:12:10 ]
教えていただいた通りにやってみたのですがディレクトリを削除しようとします。
find /tmp -mtime +1 -exec rm {} \;
ディレクトリ内のファイルのみ削除させる方法はあるのでしょうか?
よろしくお願いします。

295 名前:デフォルトの名無しさん mailto:sage [2006/07/03(月) 10:42:10 ]
-type f



296 名前:271 [2006/07/05(水) 10:00:59 ]
どうやっても上手く動作しません。
どうやってもエラーが出てしまいます。
エラーの出ない方法があれば、御教示願います。
よろしくお願いします。

297 名前:デフォルトの名無しさん mailto:sage [2006/07/05(水) 11:18:04 ]
>>296
>>295

298 名前:271 mailto:sage [2006/07/05(水) 11:31:26 ]
何度もすみません。
295さんの使い方が良くわかっていませんでした。
-type fとすることでファイルを見るというオプションだったのですね。
これで解決することができました。ありがとうございます。

299 名前:デフォルトの名無しさん [2006/07/06(木) 12:01:34 ]
DSCN0001.jpg〜DSCN9999.jpgのファイルを全てtravel2006GW0001.jpg〜travel2006GW9999.jpgに変更したいのですが
これを実現するLinuxのシェルスクリプトはどう記述したらいいですか?
それと
travel2006GW0001.jpg
travel2006GW0002.jpg



のようにtxtに打ち出すのもお願いします


300 名前:デフォルトの名無しさん mailto:sage [2006/07/06(木) 13:16:58 ]
>>299

マルチ死ね。これだからLinux使いの糞は... (ry

301 名前:デフォルトの名無しさん [2006/07/06(木) 13:23:53 ]
もう用済みじゃぼけぇwww

302 名前:デフォルトの名無しさん [2006/07/06(木) 14:08:25 ]
>>300
用済みなのは君だけ

303 名前:デフォルトの名無しさん mailto:sage [2006/07/06(木) 23:21:48 ]
>>299
#!/bin/sh
echo # | tee foo$$
cd $1
ls DSCN*.jpg | sed -e 's/\(.*\)\([0-9][0-9]*\)\(.*\)/mv \1\2\3 travel2006GW\2\3/' | tee -a foo$$
source foo$$
rm foo$$

304 名前:デフォルトの名無しさん mailto:sage [2006/07/07(金) 08:21:44 ]
>>299
$ for i in `seq -w 1 9999` ; do
for> mv DSCN${i}.jpg travel2006GW${i}.jpg
for> echo travel2006GW${i}.jpg
for> done > list


305 名前:デフォルトの名無しさん mailto:sage [2006/07/13(木) 14:49:15 ]
>>299

#!/bin/sh
for f in DSCN*.jpg
do
 f2=`echo $f | sed 's/DSCN/travel2006GW/'`
 echo $f2
 mv $f $f2
done




306 名前:デフォルトの名無しさん mailto:sage [2006/07/13(木) 16:41:26 ]
>>305
>f2=`echo $f | sed 's/DSCN/travel2006GW/'`

f2=${f/DSCN/travel2006GW}
でいいんじゃねんか

307 名前:デフォルトの名無しさん mailto:sage [2006/07/13(木) 18:24:56 ]
>>306
ああ、そうだ。bash はそれで行ける。


308 名前:デフォルトの名無しさん [2006/07/14(金) 15:56:42 ]
Bシェルを使用しています。
質問させてください。

ファイル(hoge.dat)の中のデータが下記のように3行あるとします。
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15

この中から「8,9,10」だけを取りたいと思っています。

cut -d "," -f3- $hoge.dat
では

3,4,5
8,9,10
13,14,15

を取って来るのですが、何かよい方法はないでしょうか?

よろしくお願いします。

309 名前:デフォルトの名無しさん mailto:sage [2006/07/14(金) 17:59:15 ]
そのあと普通に grep かますんじゃ駄目なの?
cut -d "," -f3- $hoge.dat | grep '8,9,10'



310 名前:デフォルトの名無しさん mailto:sage [2006/07/14(金) 18:23:08 ]
だよな
何を根拠に8,9,10なのか何も書かずにいたら
echo 8,9,10
だってりっぱな回答だ

311 名前:デフォルトの名無しさん mailto:sage [2006/07/14(金) 19:00:32 ]
これでどうだ!

awk -F, 'NR==2{for(i=3;i<=NF;i++)if(s!="")s=s","$i;else s=$i;print s}' hoge.txt

でも、未確認。


312 名前:デフォルトの名無しさん mailto:sage [2006/07/14(金) 20:50:24 ]
これでも喰らえ!
head -2 hoge.txt | tail -1 | sed 's/....//'

313 名前:デフォルトの名無しさん mailto:sage [2006/07/14(金) 21:06:11 ]
マジレス
grep -v 1,2 hoge.txt | grep -v 11 | cut -b 5-10

314 名前:デフォルトの名無しさん mailto:sage [2006/07/14(金) 21:37:57 ]
head -c 21 hoge.txt | tail -c 7

315 名前:デフォルトの名無しさん mailto:sage [2006/07/14(金) 22:33:44 ]
クマー
echo `sed -e 's/$/,/' hage.dat` | cut -d "," -f8,9,10



316 名前:デフォルトの名無しさん mailto:sage [2006/07/14(金) 23:29:04 ]
こっちのほうがいいや。
sed -ne '1h;1!H;${x;s/\n/,/g;p}' hoge.dat | cut -d "," -f 8-10

317 名前:デフォルトの名無しさん mailto:sage [2006/07/18(火) 09:56:22 ]
ええい。これでどうだ。

perl -ne 'if($.==2){chomp;print join(",",(split/,/)[2..4])."\n";}' hoge.dat

ていうか >>308 はどこ行った?

318 名前:Linax初心者 [2006/07/24(月) 23:32:10 ]
b-shallとc-shallで入力された日付が有効かどうかの確認のシェルスクリプトを作りたいのですがうるう年の計算や入力された日付が正しいかどうか判断して
正しい日付を入力させるスクリプトなんですが、初心者でわかりませんので
よろしくお願いします。


319 名前:デフォルトの名無しさん mailto:sage [2006/07/24(月) 23:42:20 ]
>>318
なんか死ね。

320 名前:デフォルトの名無しさん mailto:sage [2006/07/25(火) 01:03:54 ]
Linaxに関しては我々も初心者なもので・・・

321 名前:デフォルトの名無しさん mailto:sage [2006/07/25(火) 01:25:39 ]
えーと、スクリプトを作りたいと言うことは理解できました。
で、なにをお願いされたらよいのでしょう。

322 名前:Linax初心者 [2006/07/25(火) 06:33:39 ]
すいません初心者で。まずは日付をキーボードから
入力して存在する日付かどうか判断して、うるう年の
計算して入力された日付が正しければ、正常表示を
間違いなら、再入力を促すものです。たとえば20061313はありえない
日付ですが20060220は正しい日付でその年がうるう年かどうか
判断して2006年 2月20日 水曜日と表示したいのですが
教えていただけますか。よろしくお願いします

323 名前:デフォルトの名無しさん mailto:sage [2006/07/25(火) 08:45:49 ]
えーと、なにを教えればよいのでしょう。

324 名前:Linax初心者 [2006/07/25(火) 09:42:19 ]
すいませんが、会社の嫌がらせでまったくコンピュータ
したことがパソコンぐらいの45才です。リストラされそうなのですが
まったく知識がなくて本を読んでもよくわかりませんから
できましたらはじめから教えていただけませんか。
お願いします。うるう年の計算がわかりませんしその日が何曜日かも
わかりませんのでよろしくお願いします

325 名前:デフォルトの名無しさん mailto:sage [2006/07/25(火) 09:55:25 ]
>>324
それ以外にも足りん能力がわんさかあると見受けられるので、あきらめてホームレスって下さい。



326 名前:デフォルトの名無しさん mailto:sage [2006/07/25(火) 10:16:18 ]
とても45歳に見えない若々しいおじ様なのかしら♪

327 名前:デフォルトの名無しさん mailto:sage [2006/07/25(火) 20:40:45 ]
しかもマルチポスト

どうやって釣られてあげればいいのかな?

328 名前:デフォルトの名無しさん mailto:sage [2006/07/25(火) 22:15:54 ]
まずはマスタファイルを作るんだ

20060725,火
20060726,水
20060727,木
20060728,金
 :
 :


あとはわかるな?

329 名前:デフォルトの名無しさん mailto:sage [2006/07/25(火) 22:33:45 ]
そうそう、マスタファイルを作るスクリプトを作ればかなり効率が上がるよ


330 名前:デフォルトの名無しさん mailto:sage [2006/07/28(金) 21:58:18 ]
ディレクトリがさ
abc/ def/ ghi/
ってな風に同じ階層に3つあって、それぞれの中に
srcに対応したMakefileがあんだけどmakeすると
abc/ def/ ghi/  ~lib.a
とか自ディレクトリより一つ上に生成されてるのよ
んでabc、def、ghiどれmakeしても同じ名前のライブラリ作ってんだけど

これ作った人は何したかったのかわかんねぇ?

これが今日発生したバグですた・・・。
ぼすけてw


331 名前:デフォルトの名無しさん mailto:sage [2006/07/30(日) 22:56:47 ]
>>330
お前にはうかがい知れないすごい思想なのは分かった。


332 名前:デフォルトの名無しさん mailto:sage [2006/07/31(月) 09:15:04 ]
sed -f henkan.txt input.txt のhenkan.txtの部分を
ヒアドキュメントで書く方法ないでしょうか。無いか。
たんにテキストファイル増やすのが面倒なだけなんですが…

333 名前:デフォルトの名無しさん mailto:sage [2006/07/31(月) 11:13:36 ]
>>332
もしかして、sedスクリプトのコメントをスクリプトファイルに入れたいって話?
それともその行が書かれたシェルスクリプト内にコメントを入れたいって話?
シェルもsedもコメントは#で始まるから、どちらの場合も好きなところに書けばいいとおもうが。

334 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 00:07:14 ]
>>333
はぁ?

335 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 04:00:04 ]
>>332
複数処理なら、以下の何れかでいけると思う。

1) sed -e '処理1' -e '処理2' ... file

2) sed '
処理1
処理2
....
' file
※ 複数行をシングルか、ダブルの引用符で囲む
    囲みの中が複数行でも、sedには1つの引数として渡される

3) sed '処理1^J処理2^J...' file
※ ^J は vi で入力するなら ctrl+ESC 後に ctrl+J

OSの違いやsedのバージョンによっては駄目な方法もあるかも
シェルによって駄目とかはないと思うが、c系は自信ない



336 名前:335 mailto:sage [2006/08/01(火) 04:16:53 ]
>>332
追加でこんなんでもいいわけだが・・・

4) sed '処理1' file | sed '処理2' | sed ...

つうか、何がしたいの?
複数処理をしたいんじゃないならスレ汚し、すまんす



337 名前:335 mailto:sage [2006/08/01(火) 04:28:16 ]
ついでだからもう一つ、スレ汚しすまん
ヒアドキュメントに拘るなら、sedの代わりにedかex使え

ed file <<EOF
...
EOF


338 名前:デフォルトの名無しさん mailto:sage [2006/08/01(火) 10:14:10 ]
332です。ありがとうございます。
これだけ方法があるのにsedのmanを見て何も思い付かなかった
頭の悪さに恥じ入るばかりでございます

339 名前:デフォルトの名無しさん mailto:sage [2006/08/02(水) 06:38:49 ]
>>335
処理の中身にもよるが、こういう書き方でもたいていは動くはず。
一行でかけるし、プロセスを一つにまとめられるのでわりとお勧め。

$ sed '処理1; 処理2; 処理3; ...' file

340 名前:デフォルトの名無しさん mailto:sage [2006/08/02(水) 08:28:05 ]
>>339 プロセスを一つにまとめられるので

それじゃまるで>>335はプロセスが一つじゃないと言ってるように聞こえる。

341 名前:デフォルトの名無しさん mailto:sage [2006/08/02(水) 14:19:39 ]
>>340
そういやプロセスが複数なのは >>336 だけだったな。
レス番を間違えた


342 名前:デフォルトの名無しさん mailto:sage [2006/08/02(水) 22:11:20 ]
>>339
みんなが4000行かかるプログラムをたった1行で書いてやるぜ!的な。

343 名前:デフォルトの名無しさん mailto:sage [2006/08/02(水) 22:49:29 ]
よーし、俺がたった1行でコンソール埋め尽くしちゃる
echo *{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}


344 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 11:12:37 ]
毎月定期的に取得しているファイル名を、例えば、
filename_`date +%Y%m%d`.txt
などとして日付けを付けて保存しています。
これが先月のものと差がない場合、新しい方を破棄したくて、
date コマンドで先月の同じ日を吐き出すことができないかと思っているのですが、
date は現在の日付けを表示することしかできないのでしょうか?具体的には、
diff filename_20060801.txt filename_20060701.txt
で内容が完全に同じだったら、filename_20060801.txt を削除するようにしたいです。
環境は Linux、kernel-2.6.9-34 です。CentOS です。
どなたかアドバイスをお願いいたします。

345 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 11:53:21 ]
>>344
date -d "last month" +%Y%m%d



346 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 12:32:05 ]
うおお、それでいいんですか!
どうもありがとうございます。

347 名前:デフォルトの名無しさん mailto:sage [2006/08/03(木) 13:22:13 ]
>>345
HPUXのdateはそんな便利な機能ないからうらやましいな。
前日とかならTZ変えればいいけど

348 名前:デフォルトの名無しさん [2006/10/12(木) 15:54:09 ]
申し訳ありません。
cshで@引数が、空であるかどうかと、A引数が、数字(何桁でも可)のみ受けとる
という条件文を書きたいのですが、
@は、if ( $# -eq )や if(x$name =x)とやってもうまくいきません。
Aは、ダイレクトにif(0<=#1<=9) というやりかた?しかわかりません。

もうしわけないのですが、ご教授願えませんか?
ヒントや参考文献でもかまいません。宜しくお願いします。

349 名前:デフォルトの名無しさん mailto:sage [2006/10/12(木) 23:34:19 ]
cshやめたらいいんじゃない

350 名前:デフォルトの名無しさん mailto:sage [2006/10/13(金) 17:12:45 ]
>>348
1. 引数が空

if ( $#argv == 0 ) then
echo 空
else
echo なんかある。
endif

2. 数値かどうか

わかんねえ。こんな風にでもすれば?

set n = `echo "$argv[1]" | sed 's/[0-9][0-9]*//g'`
if ( '' == "$n" ) then
echo "$argv[1] は数値だ。"
else
echo "$argv[1] は数値ではない。"
endif


351 名前:デフォルトの名無しさん [2006/10/13(金) 18:56:57 ]
>>350
ありがとうございます。大変助かります。
やはり、sedコマンド使うんですね。
sedとawkを使うべきかなと思いながら、
あまりよく分かっていなかったんです。

これから試してみます。

352 名前:デフォルトの名無しさん mailto:sage [2006/10/13(金) 20:31:27 ]
>>351
本当は何か別の方法あるかも知れないけど、俺は知らない。

あと、その sed の使い方だとマイナス記号や小数点や数字と数字の途中にスペースが
あった場合とかが考慮されていないので、その辺は自分でなんとかして。


353 名前:デフォルトの名無しさん [2006/10/19(木) 10:01:09 ]
cshの環境で、アプリケーションログを
/backup/apl -mtime +6 -exec rm {} \;
上記のようい週次バックアップしています。

これを、直近のデータのみリストアする場合、
(最新のデータのみで、あとはいらない)
どのような表現を使えばいいのでしょうか?



354 名前:デフォルトの名無しさん mailto:sage [2006/10/19(木) 21:09:43 ]
日本語でおk

355 名前:デフォルトの名無しさん mailto: [2006/10/20(金) 22:47:35 ]
rshについて質問させて頂きます。
ある書籍に以下の記述がありました。

$ STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`

\マークが1個多いと思うのですが・・・。
正誤表には記載がありませんでした。
分かる方がいましたら是非回答をお願い致します。



356 名前:デフォルトの名無しさん mailto:sage [2006/10/21(土) 00:09:39 ]
>>355
引数が二回展開されるから。

まず local のシェルが引数を展開して rsh に
(hostname) と (sh -c 'ls; echo \$?') を渡す。

で、rsh が hostname のシェルで (sh -c 'ls; echo \$?') を実行する。
この時にもう一度展開される。


357 名前:デフォルトの名無しさん mailto: [2006/10/21(土) 11:56:53 ]
>>356
早速のご回答ありがとうございます。

>で、rsh が hostname のシェルで (sh -c 'ls; echo \$?') を実行する。
>この時にもう一度展開される。
ダブルクォーテーションで囲まれた中の$は、
シェルによってメタキャラクタと認識されてしまうので
\マークでクォートしなくてはいけないのですが、
シングルクォーテーションで囲まれた$は
メタキャラクタとは認識されないので、
\マークでクォートする必要はない、
というのが私の認識です。

よって、hostnameのシェルで実行される
(sh -c 'ls; echo \$?')の$はメタキャラクタとは
認識されないので、\マークは不要であると
思っています。

ご指摘の程よろしくお願い致します。

ちなみに今回の質問は、
書籍「入門UNIXシェルプログラミング 改訂第2版」
のP.132についてです。

358 名前:デフォルトの名無しさん mailto:sage [2006/10/21(土) 19:23:38 ]
>>357
csh 系や zsh の挙動は良く知らないが
bash のクォート除去はそこまで賢くない。

ダブルクォートの中にシングルクォートがあっても
その中身は保護されない。

例)
$ echo "$SHELL" '$SHELL' "'$SHELL'"
/bin/bash $SHELL '/bin/bash'



359 名前:デフォルトの名無しさん mailto:sage [2006/10/21(土) 20:31:06 ]
cshなんですが、
ヒアドキュメントの内容を変数に格納するのはどうやったらいいんでしょうか

360 名前:デフォルトの名無しさん mailto:sage [2006/10/22(日) 04:00:06 ]
負の遺産を量産するな。shか最悪kshで書き直せ。
(t)cshが許されるのはログインシェルまで。

361 名前:359 mailto:sage [2006/10/25(水) 13:13:03 ]
古いsoralisのメンテしてる上に周りがcshしか理解できないんで仕方なく・・・
本当はbash使いたいんですけどね



362 名前:デフォルトの名無しさん mailto:sage [2006/10/29(日) 15:43:34 ]
別に仕方ないことないだろに。


363 名前:デフォルトの名無しさん mailto:sage [2006/10/29(日) 18:22:40 ]
>>356
エスケープの処理はバッククォートとダブルクォートのときじゃないか?
rshが受け取る文字列は(sh -c 'ls; echo $?')だと思うんだけど。

(STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`)
ローカルのシェルが、バッククォートとして実行する文字を解釈 -> (rsh hostname "sh -c 'ls; echo \$?'")
バッククォートが、rshを呼び出す為に引数を展開 -> (hostname) (sh -c 'ls; echo $?')
rshがhostnameに入って、ホストのシェルで第二引数を実行 -> (sh -c 'ls; echo $?')
sh -c の処理 -> (ls; echo $?)

>ダブルクォートの中にシングルクォートがあっても
>その中身は保護されない。
ダブルクォートの中のシングルクォートは単なる文字なのでこれはこれで合ってるけど。



364 名前:デフォルトの名無しさん mailto:sage [2006/10/29(日) 23:14:19 ]
>>363
bash の man を参照するとわかるがクォートの除去は
各種展開が終わってから行われる。
冗長に処理の流れを書くとこうなる。

1. コマンド実行 -> (STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`)
2. ローカルのシェルがコマンド置換(バッククォートの処理)を行う -> (rsh hostname "sh -c 'ls; echo \\$?'")
3. サブシェルが起動してバッククォートの中身を展開する -> (rsh) (hostname) (sh -c 'ls; echo \$?')
4. サブシェルが rsh に引数 (hostname) (sh -c 'ls; echo \$?') を渡す
5. rsh が hostname のシェルに (sh -c 'ls; echo \$?') を渡す
6. hostname のシェルが引数を展開する -> (sh) (-c) (ls; echo \$?)
7. hostname のシェルが sh に (-c) (ls; echo \$?) を渡す
8. sh が引数を展開、実行する -> (ls; echo $?)
9. sh -> hostname のシェル -> rsh -> サブシェルの順に返り値が渡り、コマンド置換が終了
10. STAT に返り値が代入される

365 名前:デフォルトの名無しさん mailto:sage [2006/10/30(月) 02:27:55 ]
>>364
> bash の man を参照するとわかるがクォートの除去は
> 各種展開が終わってから行われる。
EXPANTIONSのとこにあるこれ?
The order of expansions is: brace expansion, tilde expansion, parameter, variable and arithmetic expansion and
command substitution (done in a left-to-right fashion), word splitting, and pathname expansion.

ここにあるのは、どの順で実行されていくかの説明で、クォートの解釈は別の段階だぞ。
Expansion is performed on the command line after it has been split into words.
ってあるとおり、(1)シェルが一行読み込まれる → (2)単語への分割 → (3)各要素を展開する
のうち(2)の話だ。(3)にある単語分割とは別物
#1行じゃない場合はちょっとおいといてくれ


> 2. ローカルのシェルがコマンド置換(バッククォートの処理)を行う -> (rsh hostname "sh -c 'ls; echo \\$?'")
これの前に単語への分割があって、バッククォートを使っているとバックスラッシュの前にあるバックスラッシュはエスケープとして扱われるから、
(STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`) -> (STAT) (=) (`rsh hostname "sh -c 'ls; echo \$?'"`)
この段階でバックスラッシュは一個になる。
(っていうか、そうじゃないと入れ子になったバッククォートの範囲を確定できないし)

コマンド置換の展開が実行されると、サブシェルがまた単語への分割を実施して、
今回はダブルクォートのルールに従ってバックスラッシュは$に対するエスケープ文字になる。
(rsh hostname "sh -c 'ls; echo \$?'") -> (rsh) (hostname) ("sh -c 'ls; echo $?'")


「bash -v -x」してから「echo `echo "'\\$abc'"`」ってやってみ。
読み込んだ文字と、展開結果が出てくる。
サブシェルが読み込んだ文字列は
echo "'\$abc'"
になってて、すでに一回バックスラッシュが処理されてる。



366 名前:デフォルトの名無しさん mailto:sage [2006/10/30(月) 03:36:14 ]
>>365
ほー、そうだったのか。
やっぱりこういう事は自分で検証しないとダメだな。
的確な突っ込み感謝。

367 名前:デフォルトの名無しさん mailto:sage [2006/10/30(月) 12:33:25 ]
>366
そういや、肝心の355はどこいったんだ?






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<248KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef