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

シェルスクリプト総合 その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/
0409名無しさん@お腹いっぱい。2014/03/02(日) 04:18:36.46
>>408
sed使うの得意じゃないが >>403 のように変数じゃなくて構わないなら
$ sed "/hoge/ {
a 文字列1
a 文字列2
a ・・・
a 文字列n
}" <file

とか,一旦ファイルに落としてこんな感じとか

tmpfile=`mktemp`
trap "rm -f $tmpfile" EXIT
echo -n "$str" >$tmpfile
sed "/hoge/ r $tmpfile" <file

それも嫌ならこんな形?

sed "/hoge/ r /dev/stdin" -i f1 <<EOF
$(echo "$str")
EOF
0410名無しさん@お腹いっぱい。2014/03/02(日) 05:08:57.04
あー>>404さんの方法、マッチする/banana/の部分も変数で渡したい場合は駄目でした。
/ /の中身は正規表現で解釈されちゃうからエスケープが必要ですねorz

hoge2='hoge$hoge'

echo "apple
banana
orange" | awk -v hoge="$hoge" -v hoge2="$hoge2" '{print}/hoge2/{print hoge}'


>>408
「できれば」というのは、挿入したい文字列をそのままの形でスクリプトに書いておいて、
その後の挿入処理もsedなどで華麗にワンライナーで書きたい、という願望です。

perlならできるのでしょうか。ゴミみたいな知識しかないので少し勉強しなきゃ。。
0411名無しさん@お腹いっぱい。2014/03/02(日) 06:19:37.58
>>409
/dev/stdin からsedに流せるとは驚きました!
そして、これで目的の処理がsedでできました。ありがとうございます。
以下、テストスクリプト

#!/bin/sh
searchLine=$(cat << 'EOF'
hoge'"$&hoge
EOF
)
insertLines=$(cat << 'EOF'
#### insertLine ####
#### insertLine #### '"$&%=@+-*/[](){};:!
#### insertLine ####
EOF
)
cat > f1 << 'EOF'
1: fuga
2: hoge'"$&hoge
3: fuga
EOF
sed "/$searchLine/ r /dev/stdin" f1 << EOF
$(echo "$insertLines")
EOF

結局sedに戻ってしまった。。。
sedは行マッチの / / が正規表現ではなく固定文字列というのが、この場合丁度良かったということですね。
0412名無しさん@お腹いっぱい。2014/03/02(日) 06:26:32.79
>>411
一つ補足します。
sedに渡すための searchLine に / が含まれるとsedでこけてしまう。やはり万能ではないか。。。
というかこの手の処理を完璧に汎用的にするというのは、もしかして不毛な考えなのでしょうか。

さらにおまけの補足ですが、>>404さんのようにechoの標準出力を>>411のsedへ渡す場合は、
そっちも/dev/stdinだと解釈されてしまいますね。本筋の話ではないですが。
04134082014/03/02(日) 06:47:52.02
399以降読まずに408を投稿してもうた・・・
>>410
なる。メタ文字含む複数行文字列が、挿入文字列じゃ無くて検索文字列だと勘違いしてたわ
perl -pe '$_=$_.$ENV{挿入文字列変数名} if index($_,$ENV{検索文字列変数名})>=0'
検索文字列も素の変数使うって事なら↑挟めばいいと思う
改行関連は↓にするとか「-pe」を「-lpe」にするとか挿入文字列の前後の改行で調節とか色々
perl -pe '(chomp,$_=$_.$ENV{挿入文字列変数名}) if index($_,$ENV{検索文字列変数名})>=0'

>>412
Perlなら環境変数にさえ値を入れられれば問題なく処理できるかとー
テストコード貼ろうかと思ったけどヒアドキュメント版は改行多すぎぃ!
0414名無しさん@お腹いっぱい。2014/03/02(日) 08:13:38.92
ここでは関数使ってブラックボックスにするのはアウトなんですか
0415名無しさん@お腹いっぱい。2014/03/02(日) 10:59:50.58
どうしようsedとAWKとPerl
Perl覚えたらsedとAWKでできるテキスト処理できるらしいじゃん
ワンライナーだけでも覚える価値あるかな?
0416名無しさん@お腹いっぱい。2014/03/02(日) 11:21:08.85
sedは s/hoge/fuga/ が用途の99%占めてるし
awkは {print $2} が用途の99%占めてるから憶えるまでもない
それを越える複雑な処理したい場合は素直にperlとか使うべし
0417名無しさん@お腹いっぱい。2014/03/02(日) 11:30:00.95
最近はxmlstarletも便利だけど、webだとパースできるページ少ない。
0418名無しさん@お腹いっぱい。2014/03/02(日) 14:51:52.22
>>398
特定文字列にマッチというのが正規表現なら
perl -e 'while (<STDIN>)
{
print;
if (/$ARGV[0]/)
{
print "$ARGV[1]";
}
}' "$pattern" "$insert" < file

文字列の比較なら
awk -v pattern="$pattern" -v insert="$insert" '{print} $0 == pattern {print insert}' file

て感じでどうだろう
0419名無しさん@お腹いっぱい。2014/03/02(日) 17:15:59.79
>>407
指定されてたら複製させる感じか。
明日試してみます。
0420名無しさん@お腹いっぱい。2014/03/02(日) 17:23:58.94
>>413
perl使うのなら
BEGIN{undef $/;} s/(Q${検索文字列}E)/$1${挿入文字列}/g
とかじゃダメなん?
0421名無しさん@お腹いっぱい。2014/03/02(日) 17:59:50.17
>>413,418,420
ありがとうございます。
perl全くの無知なんで勉強してみます。

# perlってなんか独特で敬遠してたのよね。。。sedやawkでできない場合に困るし、やっといたほうがいいな
0422名無しさん@お腹いっぱい。2014/03/02(日) 18:25:13.98
perlはもう10年書いてないけど困ったことはないな
rubyとpythonが書ければ何とかなる
0423名無しさん@お腹いっぱい。2014/03/02(日) 18:31:34.17
/usr/localのインストールは禁止されてるので、perlはあり得ない。
普通に sed awk あるいはシェルのみで書く。
0424名無しさん@お腹いっぱい。2014/03/02(日) 18:36:54.21
僕はnode.jsでいいです
0425名無しさん@お腹いっぱい。2014/03/02(日) 19:35:01.12
>>420
ダメじゃないと思うぞ、プログラム全般がそうだけど、Perlは特にTMTOWTDIとかいう標語まであるし
俺はそのやり方で\Eとか含んでても大丈夫って知らず、エスケープに悩みたくなくてああしただけ

>>423
そういう環境ならそうだけど…
そういう環境って組み込みとか起動中処理とかそういうケースだけのような気も…そうなるとsed awkも怪しい気がしなくもない
0426名無しさん@お腹いっぱい。2014/03/02(日) 23:51:00.24
最近はLinuxならperlはもちろんruby、pythonも入ってるのは当たり前なんだっけ?
0427名無しさん@お腹いっぱい。2014/03/02(日) 23:52:16.04
>>426
デフォルトでぜんぶ入ってるのは少ないんじゃないか
0428名無しさん@お腹いっぱい。2014/03/03(月) 01:14:07.15
FreeBSDで適当にPorts入れようとするとRubyやPython要求される
(つまりその時点では入ってない)ことが結構あった気が…Perlはどうだっけ
0429名無しさん@お腹いっぱい。2014/03/03(月) 01:50:22.24
m4もいれといて
0430名無しさん@お腹いっぱい。2014/03/03(月) 03:46:25.79
ruby入ってない@deb
0431名無しさん@お腹いっぱい。2014/03/03(月) 07:46:01.44
俺のイメージだと入ってる可能性が高い順に
python,perl,rubyだな
0432名無しさん@お腹いっぱい。2014/03/03(月) 10:51:17.61
>>431
perlが入っていないOSって何?
0433名無しさん@お腹いっぱい。2014/03/03(月) 10:56:01.93
python,perlは入ってるな大体
0434名無しさん@お腹いっぱい。2014/03/03(月) 11:00:43.61
>>432 FreeBSDだろ
0435名無しさん@お腹いっぱい。2014/03/03(月) 12:38:54.31
>>434
15年前には入っていたけど最近のバージョンには入っていないのか?
もしかしてperlはもう消えていきつつあるソフトウェアなのか?
0436名無しさん@お腹いっぱい。2014/03/03(月) 12:44:41.67
>>435
http://slashdot.jp/story/02/05/16/0611246/
この辺で外れたんじゃなかったっけ。
もちろん ports にはある。
0437名無しさん@お腹いっぱい。2014/03/03(月) 12:47:23.09
perlが消えていくってことは(今のところは)ないけど、
perl以外の選択肢は増えている。
0438名無しさん@お腹いっぱい。2014/03/03(月) 12:50:06.73
perlよりワンライナーが有用な言語ある?
0439名無しさん@お腹いっぱい。2014/03/03(月) 13:07:26.50
rubyやpythonかじったけど、普段のデータ処理は結局perl使ってるなあ
基本だけ知ってれば、いちいち調べなくても書けるのがいい
0440名無しさん@お腹いっぱい。2014/03/03(月) 13:35:31.63
>>434
NetBSDにもperlはない。
luaはあるが。
luaなのは、組み込み言語用途での実績かららしい。
0441名無しさん@お腹いっぱい。2014/03/03(月) 17:19:30.99
>>436
その記事だとカーネルビルドに必要なくなっただけでデフォルトインストールだと書かれてるけど…
0442名無しさん@お腹いっぱい。2014/03/03(月) 17:20:09.85
つーか、netbsdのカーネルに組み込まれたからね。
lrwx------ 1 root wheel 4 Feb 21 19:21 /dev/lua -> lua0
crw-rw-r-- 1 root wheel 209, 0 Feb 21 19:21 /dev/lua0
0443名無しさん@お腹いっぱい。2014/03/03(月) 22:49:22.36
最近猫も杓子もpythonな風潮が気に入らない
0444名無しさん@お腹いっぱい。2014/03/03(月) 22:57:48.86
>>443
シェルスクリプトと言い張る。

#!/bin/sh
python -c hogehoge...
EOF
0445名無しさん@お腹いっぱい。2014/03/04(火) 00:24:58.61
>>444
pythonなら

#!/bin/sh
python <<EOF
hogehogehoge
EOF

にしないとワンライナーで書くことになって死ぬ
0446名無しさん@お腹いっぱい。2014/03/04(火) 05:16:11.99
冷や毒は添付ファイル作るから、/tmpが書き込み不可(boot時など)の時動作しない。
豆な。
0447名無しさん@お腹いっぱい。2014/03/04(火) 08:37:46.65
当て字きもい
0448名無しさん@お腹いっぱい。2014/03/04(火) 09:10:08.09
そんなあなたに冷やすとリング
0449名無しさん@お腹いっぱい。2014/03/04(火) 11:04:27.79
2ch とはいえ技術系スレだもんな。

技術系スレとはいえ 2ch だもんな。

どっちが大勢?
0450名無しさん@お腹いっぱい。2014/03/04(火) 11:20:14.56
そういうのは別のスレで。
0451名無しさん@お腹いっぱい。2014/03/04(火) 11:39:52.72
そういう詰まらんオマエは別のスレへ。
0452名無しさん@お腹いっぱい。2014/03/05(水) 06:45:09.19
>>446,448 みたいな当て字書くプログラマーorシス管見つけたら
社史編纂室に異動させるわ
0453名無しさん@お腹いっぱい。2014/03/05(水) 06:52:27.27
当て字に塗れた社史とか読みたくないです
0454名無しさん@お腹いっぱい。2014/03/05(水) 08:13:05.63
>>448
冷やすとリングも添付ファイル作るから解決にならんよ。パイプで書き換えること。
0455名無しさん@お腹いっぱい。2014/03/06(木) 00:46:35.73
cshでは以下のようなことはできないのでしょうか。

set usage="usage : `basename $0` -hoge [A|B|C]"

[]でエラーになります。
0456名無しさん@お腹いっぱい。2014/03/06(木) 02:36:44.78
>>455
>>1
> ・csh/tcshのシェルスクリプトは推奨されません。
>  (理由は「csh-whynot」でググれ)
ログインシェルとして使うのはともかく、スクリプトにcsh系を使うべきではない
0457名無しさん@お腹いっぱい。2014/03/06(木) 06:26:36.56
社史編纂室に異動させてほしいです。

仕事なくても養ってくれるなんて、今どきあり得ない好待遇じゃないですか。
左遷される前にクビが飛ぶんですから。
0458名無しさん@お腹いっぱい。2014/03/06(木) 06:29:01.28
そのかわり人格破壊作業を施されるとか
0459名無しさん@お腹いっぱい。2014/03/06(木) 07:47:00.96
社史や社史編纂室を作る余裕があるような会社に就職したいです
0460名無しさん@お腹いっぱい。2014/03/06(木) 08:22:34.96
>>455
使ってないけど、
set usage="usage : `basename $0` -hoge "'[A|B|C]'
じゃダメなの?
0461名無しさん@お腹いっぱい。2014/03/09(日) 03:02:15.61
PS1やエイリアスを指定した状態でbashを起動し
対話操作できるようにできますか?
bashをヒアドキュメントを利用して起動してもbashが終了してしまい-cオプションでも同じことが起きます
-o ignoreeofでもダメでした
0462名無しさん@お腹いっぱい。2014/03/09(日) 09:24:16.63
>>461
環境変数だけなら env PS1="..." PS2="..." /bin/bash でいける。
別途ファイル用意していいなら bash --rcfile ファイル名 で .bashrc のかわりのファイルを指定するか。
(ファイルの先頭に . ${HOME}/.bashrc 書いておいて、追記分を2行目以降に記載)
0463名無しさん@お腹いっぱい。2014/03/09(日) 10:05:44.59
すみませんが詳しい方のみ回答をお願いします
0464名無しさん@お腹いっぱい。2014/03/09(日) 10:10:03.69
すみませんが2chに詳しい方のみ質問をお願いします
0465名無しさん@お腹いっぱい。2014/03/09(日) 23:13:53.66
こういうのってぼっとなのかな?
手でやってるのかな?
0466名無しさん@お腹いっぱい。2014/03/10(月) 06:29:01.50
超高性能ボットみのような人間がやってるんじゃね?
人工知能はいまだ自然言語の分解も怪しいってのに
質問と回答とその他が区別できる程の自然言語解釈とか無理だと思う
0467名無しさん@お腹いっぱい。2014/03/10(月) 06:48:59.22
そうだな。的を外してる回答のみを抽出する処理も要るしな。
0468名無しさん@お腹いっぱい。2014/03/10(月) 09:20:03.93
社なんとか室の仕事じゃね?w
0469名無しさん@お腹いっぱい。2014/03/10(月) 13:43:45.94
PS1はプロンプトでしょ?
PS2ってなんだっけか
0470名無しさん@お腹いっぱい。2014/03/10(月) 13:45:31.00
セカンダリプロンプト
0471名無しさん@お腹いっぱい。2014/03/10(月) 13:47:51.38
自動的にプログラム実行時の実時間を環境変数に入れるように
プロンプトを改造したいんだけど、うまくいきません。

bashで、プログラム実行直前の時刻を取得する方法ってあります?
bashで無理ならzshとかいうやつでもいいです。
0472名無しさん@お腹いっぱい。2014/03/10(月) 13:48:41.84
だからセカンダリプロンプトってなんだっけかって聞いてるんだろ。アスペかよw
0473名無しさん@お腹いっぱい。2014/03/10(月) 13:50:14.23
man読めよ。
0474名無しさん@お腹いっぱい。2014/03/10(月) 14:42:21.01
>>471
あるよ
0475名無しさん@お腹いっぱい。2014/03/10(月) 14:43:20.91
すみませんが詳しい方のみ回答をお願いします
0476名無しさん@お腹いっぱい。2014/03/10(月) 21:50:55.09
history-all | tail
あたり
0477名無しさん@お腹いっぱい。2014/03/11(火) 10:38:49.35
>>474
どうやって実現すればよいですか?
0478名無しさん@お腹いっぱい。2014/03/11(火) 10:56:29.86
ないよ
0479名無しさん@お腹いっぱい。2014/03/11(火) 13:17:02.19
historyじゃだめなの?
HISTTIMEFORMAT環境変数セットして
0480名無しさん@お腹いっぱい。2014/03/11(火) 14:36:12.29
プロンプトに時刻入らなきゃヤダ。
プロンプト表示時点の時刻じゃなくて、
コマンド実行時にそのコマンドをタイプした前の行のプロンプトに時刻を入れる
というところがポイントな。
0481名無しさん@お腹いっぱい。2014/03/11(火) 14:45:31.55
現在コマンド入力中のプロンプトは時計のように時刻を1秒毎にカウントアップしていて、
コマンドをタイプしたらその行プロンプトのの時計が止まってコマンド起動時刻を示す、
というのがいいな。
0482名無しさん@お腹いっぱい。2014/03/11(火) 15:11:12.45
historyに時刻入れた方が便利そう。
0483名無しさん@お腹いっぱい。2014/03/11(火) 15:48:25.57
>>479
HISTTIMEFORMATセットすると、
HISTCONTROL=ignoreboth が無効になる
当たり前なんだろうけどちょっとショック受けた
0484名無しさん@お腹いっぱい。2014/03/11(火) 16:31:57.44
実行直前の時刻って何なの?開始時刻とは違うの?
0485名無しさん@お腹いっぱい。2014/03/11(火) 16:54:41.94
呼ばれたコマンドが始まってしまったら
シェル側はどうこうできない。
呼ばれるコマンドが実行される直前に
シェル側で時刻を出す必要がある。
0486名無しさん@お腹いっぱい。2014/03/11(火) 18:11:36.64
>>484
違わない
実行直前の時刻とは、開始時刻のことである
必要ならば図解しようか?
0487名無しさん@お腹いっぱい。2014/03/11(火) 18:13:28.44
>>486
図解よろしく。
0488名無しさん@お腹いっぱい。2014/03/12(水) 08:46:30.76
tcshユーザやzshユーザはprecmd使えるから何も悩まずに出来そうなんだがなぁ…
bashでprecmdをググったらこんなのが引っかかった ttp://glyf.livejournal.com/63106.html
0489名無しさん@お腹いっぱい。2014/03/12(水) 23:40:38.94
パスワード認証のsshでログインを自動化したいのですが、どのようにすればよいでしょうか?
expectコマンドはインストールしない方法を考えています。

echo -e "password\n" | ssh -t -t root@hoge.hoge

上のスクリプトだとプロンプトが出てダメでした。よろしくお願いいたします。
0490名無しさん@お腹いっぱい。2014/03/13(木) 00:06:43.46
>>489
失礼な話だが、釣り/荒し臭い質問だな。
適当に回答させて、いつものお決まりの文を書き込むのかな?
0491名無しさん@お腹いっぱい。2014/03/13(木) 00:10:32.95
expectが何を出来るかしか知らないんだろうな。
expectが何をやってるか知っていればそんなマヌケな質問は出てこない。

回答:
expect入れたくなきゃexpectと同じ働きのプログラムを作る
0492名無しさん@お腹いっぱい。2014/03/13(木) 00:12:25.76
>>489
何故パスフレーズなし秘密鍵ではだめなの?
0493名無しさん@お腹いっぱい。2014/03/13(木) 00:17:52.08
>>492
Dockerのコンテナにsshでログインしようとしているのですが、秘密鍵を指定しても読み込んでくれずパスワード入力になりました。
それで秘密鍵なしで頑張ろうと試行錯誤している次第です。
0494名無しさん@お腹いっぱい。2014/03/13(木) 00:18:14.48
>>492
ぼくのかんがえたさいきょうのパスワードくらっかーで、にっくきあいつのホストにろぐいんしてやるんだー。
ってことだろ
0495名無しさん@お腹いっぱい。2014/03/13(木) 00:19:50.07
>>493
公開鍵方式で認証できるように試行錯誤しろよ。
0496名無しさん@お腹いっぱい。2014/03/13(木) 00:34:58.01
>>493
$HOME/.ssh/authorized_keysないし、その祖先ディレクトリの
どこかが、グループかotherに対して書き込みを許してるってのが
チョーありがち。
てゆーか、まずログを確認すべきだね。
CentOSなら/var/log/secureとか。
0497名無しさん@お腹いっぱい。2014/03/13(木) 00:54:40.58
>>496
$HOME/.sshフォルダがまるごと消えていたのが原因だったようです。。
きちんと確認しないといけないですね。ありがとうございました。
0498名無しさん@お腹いっぱい。2014/03/13(木) 01:43:17.07
何それww
0499名無しさん@お腹いっぱい。2014/03/13(木) 10:38:52.37
このスレには社史編纂室レベルの質問しかこないのか
0500名無しさん@お腹いっぱい。2014/03/13(木) 19:05:06.07
噴いた
0501名無しさん@お腹いっぱい。2014/03/14(金) 03:42:52.41
>>499
答えてるのも社史編纂室のおじちゃん達というオチか
0502名無しさん@お腹いっぱい。2014/03/14(金) 09:07:38.64
社史編纂室厨いい加減うざい
糞質問する奴ともども氏ねや
0503名無しさん@お腹いっぱい。2014/03/14(金) 09:43:44.60
bashで、プログラム実行後のカレントを保存する方法ってあります?
bashで無理ならzshとかいうやつでもいいです。
0504名無しさん@お腹いっぱい。2014/03/14(金) 10:14:10.84
老けたせいでギャグの質が低下してるのを気がつかないのだろう

社史編纂質
すみませんが詳しい方だけ答えてうんたら

これらギャグのつもりなんだろうが
面白くないし、寒いし、うざい
「ギャグは繰り返し」を勘違いしてる、寒くてうざいもんは寒くてうざい
0505名無しさん@お腹いっぱい。2014/03/14(金) 10:23:30.00
老化してるから
「ウざがられるためにやってるんですう」とか
小学生みたいにいってくるからヤメロ
0506名無しさん@お腹いっぱい。2014/03/14(金) 11:05:31.46
>>503
カレントってなに? 電流?
0507名無しさん@お腹いっぱい。2014/03/14(金) 11:37:04.63
カレントディレクトリか?
DIR=`pwd` とかそういう話かな。
0508名無しさん@お腹いっぱい。2014/03/14(金) 11:38:08.74
DIR=$PWD でいいか。
■ このスレッドは過去ログ倉庫に格納されています