シェルスクリプトの総合スレです。
□お約束
・特記なき場合は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/
おつ
bash なら exponent は ** なのにな
case文を抜け出す方法はbashには無かったけど
ほかのシェルでcase文から抜け出す方法はある?
;;でcaseから抜けるけど
if [ $? -eq 0 ]; then
みんな、$? は""で囲う派? 囲わない派?
普段は囲まないけど、誰かの書いたのをいじるときはそれに合わせるよ派
数値なので囲わない派
$前に0付ける派
$の前に0つけるのってファイナルビューティ醸してるな。
この発送はなかった。
$ test 12 -eq 12; echo $?
0
$ test 012 -eq 12; echo $?
0
>>13 あ、使ってる関数は自動変換するけど、10進数限定にもできて、testは限定されてた。
だからやっぱりないw
マイナス
"負数"が返ってきたらアウトだな
と思ったけど実行結果は必ず0か自然数なので問題なかった
16 :
名無しさん@お腹いっぱい。:2013/11/10(日) 17:23:11.15
あるファイルが、実行可能な設定ファイルであることを
チェックして保証したいんだけど、なんかいい方法ある?
手抜きなんかしないで、ひとつひとつちゃんと
HOGE="PIYO"
みたいなフォーマットにのっとってることを
文法チェックして確認しないとだめ?
17 :
名無しさん@お腹いっぱい。:2013/11/10(日) 19:40:09.82
実行可能って、エラーを発生させることなくパース可能という意味?
任意の書式だと困難だと思うけど。
それは秘密
それがわからないと答えにくい。
そのファイルでどこまでの記述を許すかによるんじゃない?
a="b" の範囲内ならgrepでできるかもしれない。
a=${hoge:=piyo} とかも許すなら、俺しらね。
さらにシェルで書けることならなんでもOKとするなら、
本気でパーズしなきゃだめだろ。
シンタックスが正しくてもセマンティクスが正しくなければ
「実行可能」ではないのでは?
16はもう来ないのか?
bashがデカ過ぎる…。そして重過ぎる…。
>>17 そうだね
>>21 設定ファイルとして使いたいけど実装は面倒なので実行で済ませたい
って横着な話が起点なので、いい方法がなければ自力でチェックします。
bash -r とか使えるかなと思ったけど無意味っぽかった
ならスクリプトとして完全なチェックは必要ないよね。
自力でもそんなに難しくないんでは。
一定時間、何度か繰り返しコマンドを実行したくて、
for i in `seq 1 10`
do
何かのコマンド
sleep 1h
done
echo "finished" | write username
といったスクリプトを書いているのですが、このやり方だと
最後にコマンドを実行してから一時間、無駄に sleep してしまいます。
最後の sleep だけ実行しない方法はないでしょうか。
再編集の時が恐いけど
変数 i<=9 のときにsleep 1h
か
i/=10の時に sleep 1h
>>27 i=10
while
何かのコマンド
((--i)) && sleep 1h
do :; done
echo "finished" | write username
30 :
27:2013/11/20(水) 20:07:56.43
おお! 素早い回答、ありがとうございます。
ですが、たびたびすいません。
実際に使っているスクリプトだと、ループの実行回数が不定な場合があるのです。
(行数が特定できないファイルからの読み込みとか)
最後のループでは sleep しない、という手段はあるでしょうか。
31 :
27:2013/11/20(水) 20:19:58.58
よく考えたらファイルからの読み込みも終了判定できますね。
何とか工夫すれば、判定できないループってないかも……。
どうもお騒がせしました。
>>29 ((--i)) でiが0になる時、返り値1なんだ。
iが負の値になる時でも返り値0なのに、0になる時だけ特別なんですね。
33 :
名無しさん@お腹いっぱい。:2013/11/21(木) 00:11:48.01
If the value of the expression is non-zero, the
return status is 0; otherwise the return status is 1.
pingを打って 成功⇒次のping 失敗⇒EXIT
もっかい別のとこにping 成功⇒ログ出力 失敗⇒コマンド実行
こんな感じのスクリプト作りたいんだけど
pingの結果って$?に入るんだよね
これって複数あった場合どうすれば良いの?
>>34 直前のコマンドの結果で毎回 $? が上書きされるだけ。
37 :
34:2013/11/21(木) 23:26:22.05
わかり難くてすません
1.ping打つ 成功⇒2へ 失敗⇒終了
↑ココの$?
2.ping打つ 成功⇒ログ書き込み 失敗⇒コマンド実行
↑ココの$?
で結果を分けて処理しようと考えてます。
根本的に考え方が違うなら考えを改めるよ
38 :
34:2013/11/21(木) 23:28:11.31
>>38 >>36 の回答は理解できないの?
hoge=$? でコピーしておいてもいいし
40 :
34: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
if ping -c 3 192.168.43.1 >/dev/null; then
if 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
全角空白は置換してくれ。
42 :
34:2013/11/22(金) 00:08:55.90
おいおい条件要らないとかマジかよ
意外とスクリプト面白いな
条件要らない?
どういうこと?
ifが変数に入れなくてもそのまま戻り値でいけるってとこじゃね?
ifに条件は要るだろ。
ping -c 3 192.168.43.1 >/dev/null && { ping -c 1 192.168.254.100 >/dev/null && echo Status=OK || { /etc/script/wol 192.168.254.255 10:78:D2:4B:D6:55; echo WAKE-ON-LAN; }; } || echo NoThanks
if使わない方法もあるのね。なかなか勉強になるぜ
>>43 [ ${PING1} -eq "0" ];これってpingの変数が0だったらって条件じゃないの?
1とか他の値だったら条件に合わないよね?
でも
>>41のを見るとそんな条件なく成功=次へって感じに見えるけど
何処に条件が書いてあるん?
分かり易く教えてくだしあ
if は、条件がどうこうじゃなく、コマンドの戻り値で判断する文法。
[ ... ] の [ は、ifの文法じゃなくて [ という名前のコマンド。
testコマンドじゃなかったか? => []
test と [ は同じ物。
コピーかリンク。
] は関係ない。
51 :
名無しさん@お腹いっぱい。:2013/11/23(土) 00:41:18.75
test を [ という名前で起動するときは、
最後に ] という引数を要求するようになっている、という仕組み。
ping文が条件じゃん。
f=
if [ -f "$f" ]; then
echo "ファイル$fはある"
else
echo "ファイル$fはない"
fi
を実行すると、
ファイルはない
f=
if [ -f $f ]; then
echo "ファイル$fはある"
else
echo "ファイル$fはない"
fi
を実行すると、
ファイルはある
"$f" でないと「ある」になるんですが、
そんなファイルはないのに、なぜなんでしょう?
[ -f $f ] は [ -f ] と同じ意味になって、
[ コマンドがそれを真とみなすから。
[ -f "" ] && echo hoge
と
[ -f ] && echo hoge
ってことだな。
>>54 なぜ真とみなされるのか、という疑問では。
-f が単なる文字列として解釈されているのでは
`-n STRING'
`STRING'
True if the length of STRING is nonzero.
マニュアルには -f file の場合しかないんで、-f だけだと未定義。
ということは、真になろうが偽になろうが利用者は文句を言えない。
最初の実装上たまたま真にしたんじゃね?
で、その実装がそのまま引き継がれていると。
以上、想像。
59 :
53:2013/11/23(土) 19:57:40.35
さすがこのスレは物知りが多いですね
$ test hoge
$ echo $?
0
だから
$ test -f
$ echo $?
0
も同じってことですか なるほど
しかし、わかりにくいってか間違いやすいなー
>>57 ああ、なるほど。鼻から悪魔が出てくるアレと同じ構図なのか。
opencobolでプログラムを書いて、bashシェルで実行させています
その時、シェルでファイルを定義する必要があるんですが、
AAAAAA=./work/AAAAAA.txt ; export AAAAAA
echo AAAAAA=$AAAAAA
を複数書く必要があるんですが、
AAAAAAを何ヵ所も書き換えるのが大変です
皆さんならどう定義しますか?
どういうこと?
64 :
名無しさん@お腹いっぱい。:2013/11/25(月) 10:27:09.96
下のTEST001プログラムを実行するときに、IN1FILE,IN2FILE,OUT1FILEを定義する必要があります。
もっとわかりやすくて、書きやすい方法ないのかと思い、相談させてもらいました。
現在下のような感じです。
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 " "
echo が必要なら書くしかないんじゃね。
bash 前提なら
export IN1FILE=${mastpass}IN1FILE.txt で済む。
66 :
名無しさん@お腹いっぱい。:2013/11/25(月) 10:40:53.46
こんな感じで、一か所変更すれば良い様にしたいんですが、
いまいちshellがわかってなくて・・・
FIL=IN1FILE ; '$FIL=${mastpass}$FIL.txt ;export $FIL ;echo $FIL = $FIL
eval使え
68 :
名無しさん@お腹いっぱい。:2013/11/25(月) 10:51:08.10
>>65 ありがとございます
参考にいろいろやってみてます。
最後の'$'$FILの所がうまく行きませんでした。
FIL=KANFIL ; export $FIL=${mastpass}$FIL.isam ; echo $FIL = '$'$FIL
70 :
名無しさん@お腹いっぱい。:2013/11/25(月) 10:57:21.15
↓で出来ました。ありがとうございます。
もっといい方法ありますか?
FIL=IN1FILE ; export $FIL=${mastpass}$FIL.txt ; eval echo $FIL = '$'$FIL
汎用機からマイグレをしようと思ってます。
JCLが出力しているような情報は出力させたいので、
echoは必要だと考えています。
71 :
名無しさん@お腹いっぱい。:2013/11/25(月) 11:02:38.40
あと、プログラム終わった後、環境変数を解放してあげる必要があるかと思うんですが、
その場合は、配列にして、
@配列定義
A配列を使ってexport定義
Bプログラム実行
C配列を使ってunsetで解放
って感じが良いのでしょうか
>>71 > あと、プログラム終わった後、環境変数を解放してあげる必要があるかと思うんですが、
そうなん?
73 :
名無しさん@お腹いっぱい。:2013/11/25(月) 11:13:38.62
>>72 汎用機ばっかりだったので、
ファイルを使いたいときは定義、使い終わったら解放ってのが一般的だと思ってたので・・・
次のプログラムでは、定義してないファイルは使えない感じの方がいいのかと思ってますが、
そんな考え方は、必要ないのでしょうか?
define_file()
{
local FIL=$1
eval "$FIL=${mastpass}$FIL.txt ;export $FIL ;echo $FIL = \$$FIL"
}
define_file IN1FILE
define_file IN2FILE
define_file OUT1FILE
環境変数はシェルスクリプトに閉じているからシェルスクリプトが終了すれば消えてなくなる
あとpassってなんだよ。pathの事か?
パスワードのことじゃね?
にゃんぱすー
77 :
64:2013/11/25(月) 12:01:10.93
>>74 pass=pathです
恥ずかしいから誰にも言わないで下さい
78 :
64:2013/11/25(月) 12:34:00.24
>>74さん
ありがとうございます。
理想的な感じです!!
define_fileを外部ファイル(外部シェル)とする事もできますか?
将来的には、ファイル名、属性、フォルダを渡したいと考えています
define_file IN1FILE mast txt
> define_fileを外部ファイル(外部シェル)とする事もできますか?
そのシェルの中でevalしないとダメ
別ファイルに記述しといて ドットコマンドで定義を読み込むことは出来る
. define_file.inc
80 :
64: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
なんつうか、COBOLはもともとの発想というか方法論が違うんだな…
82 :
名無しさん@お腹いっぱい。:2013/12/04(水) 13:08:09.83
cshは関数作れなかったり、各種制御がお粗末だったり色々問題ありなので、shでスクリプトを書こうとしています。
しかし、一部の設定でcshの文法で書かれたファイルをsourceする必要があります。
(cshスクリプトファイルで設定される$pathや環境変数などの設定情報が必要)
shスクリプト内で単純にsourceするとファイルがshで解釈されてエラーになります。
どのようにすれば、shスクリプトでcshスクリプトファイルの設定を引き継げますでしょうか。
shに書き起こすのは無しで、ファイルそのものを使えるのが理想です。
>>82 cshで読んで、子プロセスとして起動したshに環境変数として渡す。
前処理が必要ならsh→csh→shの入れ子にして動かす。
すみませんがcshがインストールされていないLinuxの前提でお願いします
既読スルー
>>84 変数代入に相当する構文をgrepで抽出して解釈。
ifブロック内での変数操作を拾う点については諦める。
それも嫌ならcshを無理矢理でもいいから突っ込んで動かせ。
87 :
名無しさん@お腹いっぱい。:2013/12/04(水) 14:50:40.08
csh2sh と名のつく変換スクリプトもいろいろあるようだよ。
csh2shみたいのじゃだめなんかな。
すみませんが若い女性の方のみお願いします。
90 :
名無しさん@お腹いっぱい。:2013/12/11(水) 19:06:34.35
dashはうんこだと思う
既読スルー
若い女性がダッシュでウンコの動画マダー?
Software Design 2014年1月号
シェル特集だぞ。
なんか、良いこと書いてる?
94 :
名無しさん@お腹いっぱい。:2013/12/27(金) 13:24:08.23
冬休みにシエルを始めたいのですがどのアプリを入れればいいのかいっぱいあってわかりません。オーエスはアンドロイドです。よろしく教えてください。
釣りにしか見えない
97 :
名無しさん@お腹いっぱい。:2013/12/27(金) 15:10:37.86
すみませんがプレイのアプリでお願いします
>>99 ありがとうございます。いま環境がないので姉が帰ってきたら試してみます。
101 :
名無しさん@お腹いっぱい。:2013/12/27(金) 17:31:10.29
urlくらいまじめに見ろよ
釣りのような気もするがマジレスすると、ConnectBotでいいと思う。
こいつはsshクライアントなんだが、デフォルトだとプロトコルsshって
表示されてるとこでプロトコルlocalを選ぶと、Androidの
一般ユーザー権限でシェルが使えるので。
釣りっていうかすべったネタ。
Androidだとふつーにシェルが使えるから、釣り/ネタにならんのよね。
iOSならネタになるかな?
iOSの公式ストアにあるアプリで、ローカルのシェルが使える奴ってある?
釣りにしか見えない
まあデフォルトだとsedもawkも入ってないので、
だいぶ厳しい。(grepは入ってる)
でもシェルはkshで行編集やファイル名補完は効くぞ。
なぜかmoreがあるなあと思ったら、これksh組み込みの奴だったのね。
標準入力(od -xが出力した文字列)の文字列を4バイトごと切り取り、
それをforループで処理させたい思っており、現在はこんな感じのスクリプト作ってます
OSはCentOS、シェルはbashです
#!/bin/sh
for STR in `4バイトごとに切り取る処理`
do
hogehoge $STR
done
この「4バイトごとに切り取る処理」ですが、現在はsplitで4バイト単位に切り取り、
分割後のファイルを順次読み込ませるということにしているのですが、
分割後のファイルが沢山作られるので遅くなり、またやりたい事の割にやってることが
複雑すぎるので、なんとか改善したいと思ってます
そういうことをしてくれる、いい方法はありますでしょうか
標準出力を、指定したバイト数単位にセパレータを挟んで出力してくれるコマンド、みたいな
cutでやってみようと思ったのですが、これだとオフセットを4バイトずつずらしながら
切り出していく処理となりそうで、これもまた複雑だなぁ、と…
$ echo 'hogefugapiyo' | while read -N 4 STR; do echo $STR; done
ふらっと通りがかったが感動した!
107です
>>108 なるほどreadでやるのですね
バイト数も任意で変更できそうで、柔軟性もありますね
ありがとうございました
>>108 つfold
じゃだめなんだっけ?
forをwhileに書き換えるのはおすすめしない。
>>108 read: Illegal option -N
113 :
名無しさん@お腹いっぱい。:2014/01/11(土) 15:13:02.47
dd bs=1 count=切り出しバイト数 skip=オフセットバイト数
でなんとかならんかい?
> 標準出力を、指定したバイト数単位にセパレータを挟んで出力
fold だとセパレータの指定はできないんじゃない?
$ sep="@"; echo 'hogefugapiyo' | while read -N 4 str; do echo -en "${str}${sep}";done
とかしたいのかと思ったけど…
# 最後にセパレータがくっついちゃうけどね
read に -N オプション付けてるプログラマーorシス管見つけたら
社史編纂室に異動させるわ
echo 1 2 3 | read k1 k2 k3 | echo $k1 $k2 $k3
1 2 3
echo 1 2 3 | read k1 k2 k3 | echo $k1 $k2 $k3 | read kk1 kk2 kk3 | echo $kk1 $kk2 $kk3
パイプって何本までできる?
>>115 sed に -r つけたり grep に -P オプション付けてたりしたら
どこへ異動させられるやらw
>>117 シェルがあえて限界を設定していないなら
1コマンドとして処理できる文字数以内で
単一プロセスが開けるパイプの限界数まで
じゃね?
>>117 これって動く?サブシェルになりそうな気がするんだけど
>>117 みたいなスクリプト書くプログラマーorシス管見つけたら
社史編纂室に異動させるわ
>>107 odじゃ無いけどhexdumpの-fフォーマット辺りで何とかならんかのー
ln -s original linked
ln -s linked linked_linked
みたいにリンクのリンク状態になっている場合、
シェルスクリプト内で、最後の linked_linked から大元のファイル
(この場合は original)を探り出す簡便な方法ってありますか?
$ readlink -f linked_linked
126 :
124:2014/01/18(土) 00:38:34.41
>>125 ありがとうございます!
そんなコマンドがあったとは!
bash -c "test.sh 1 2 3"
とコマンド文字列を引用符で囲うところで引用符を忘れて
bash -c test.sh 1 2. 3
としてしまった場合、 1 2 3 はどこに行ってしまうのでしょうか。
気になって仕方がないので教えてくださいー
>>127 bash -c 'echo $0 $@' 1 2 3
ってやってみるとわかる
129 :
名無しさん@お腹いっぱい。:2014/01/18(土) 14:38:07.29
シェルから、端末のビープ音を鳴らすまたはバイブする方法を教えてください。
通常端末と違って echo -e '\a' では駄目です。Androidです。
127です。
おおお凄い引数として扱える、、、、ってでもこれはナンダ?
-c で生成したプロセスのbashに対して引数を与えられる、ってことでいいのかな?
まだよく理解できていませんが、色々と試してみようと思います。
128さん、ありがとうございました!
131 :
名無しさん@お腹いっぱい。:2014/01/19(日) 02:14:50.20
a.txt には CHINKO=BIG というテキストが入っています
IFS='=' read A B < a.txt
なら思ったとおりに AにCHINKO、BにBIG が入るんだけど
cat a.txt | IFS='=' read A B
だと入ってくれません
これって何が原因に考えられますか?
入ったけど。
$ IFS='=' read A B < a.txt; echo $A; echo $B
CHINKO
BIG
$ cat a.txt | IFS='=' read A B; echo $A; echo $B
CHINKO
BIG
$
わかった。
Debianだとうまくいかないんだ、shがdashだから。
>>132 ありがとうございました
dashでも入ったけど。
えー・・・
>>129 \aとかのビープを鳴らすってことならターミナルエミュレータが\aでビープなりバイブなりを再現すればいい
ので、ターミナルエミュレータの開発元に物申せばいいと思うよ。
普通に鳴らすコマンドが有るかは・・・知らん。
プログラムのファイル入出力はシェルでどう指定したらいいの?
>>136 いま、ConnectBot 上で echo Control-V Control-G したら、ちゃんと
ビープしたな。
プログラムを作成する上で、ファイルを入力または出力するには、シェルでどのような指定を行なえばいいですか?
プログラムってのがシェルスクリプトで
文字列なら入力はcatとかで変数にいれたらいい
var=`cat hoge.txt`
出力は標準出力からリダイレクト
hoge.sh > hoge.txt
バイナリならxxdとか使って16進数に変えてから使えばいい
142 :
141:2014/01/19(日) 09:51:46.11
やりたいことがわからないからこれでいいかは知らないが。
>>140 何を言いたいのかよくわからんが、
もしシェルをJCLのようなイメージでとらえているのであれば、
プログラムを作成する上で、シェルは必要ないです。
プログラムの中で指定すればいい。
ファイル名いろいろあるやん。
146 :
名無しさん@お腹いっぱい。:2014/01/24(金) 08:44:32.88
Cシェルで変数$hogeにAAAをセットし、さらにAAAの先頭にタブ文字を挿入して<タブ文字>AAAと表示させる方法を教えて下さい。
Cシェル使こてるプログラマーorシス管見つけたら
社史編纂室に異動させるわ
もうそれ飽きた。
千行以上あるUNIXTIMEを変換するのに一番効率のいいやりかたって、ありますか?
いまのところwhileにリダイレクトで食わせてreadで1行ずつperlで変換させてます。
もとはBINDのnamed.statsで、UNIXTIMEだけ抽出したものなんですけど、
えっらい時間をとられるもので…
ちなみにHP-UXだからか、dateにstrf表示させられなかったです。
>>149 うーん、perl で直接ループ回しちゃえばいいんじゃないかな
$ perl -pe 's/\d+/localtime $&/e' < named.stats
named.stats のフォーマットが分からないから "\d+" が別の文字列に
マッチしちゃうかもしれないけど。
そこで全部perlで回すかと思わず
2ちゃんねるで聞こうとなる思考がどうかしてる
そこで全部シェルで書こうかと思わず
perl(笑)に逃げちゃう思考がどうかしてる
「自分、perlに逃げたりしないで全部シェルで書くんで待ってください」
辞令
史編纂室勤務ヲ命ズ
シェルでそんなことしたらスループットすげー低そう
>>150 ありがとうございます。
別にスクリプト書いてそっちで回すか、Excelで計算するか…しかなさそうですね。
やってることは、こんな感じです。
grep "+++ Statistics Dump +++" named.stats | awk 'BEGIN{FS="("}{print $2}' | sed 's/)//' > days.txt
(他にもグラフ化したい値を抽出してテキスト化(略))
paste -d, days.txt hoge.txt fuga.txt > data.csv
>>154 すごく…… 低いです……
ン万行あってもgrepであっさりと情報をぶっこ抜けるので、ここだけ、
days.txtのUNIXTIMEを変換する、ここだけ遅いんですよ…
perlで全部解析するスクリプト組むとか面倒で
全部解析するスクリプトもなにも
いまの1行変換処理をループで囲うだけでしょ
while(<>){ 処理; }
>>155 他が問題ない速度なら変換する部分だけをperlに置き換えればいいでしょ
>>155 >grep "+++ Statistics Dump +++" named.stats | awk 'BEGIN{FS="("}{print $2}' | sed 's/)//' > days.txt
せっかく awk 使っているんだからこれで↓
awk -F'[()]' '/^\+\+\+ Statistics Dump \+\+\+/{print $2}' named.stats > days.txt
>>155 perl でやるならこれで↓
perl -ne 'if(/^\+\+\+ Statistics Dump \+\+\+ \((\d+)\)$/){print localtime($1) . "\n";}' named.stats > days.txt
>>158 awk には strftime() が使えるからこれで↓
awk -F'[()]' '/^\+\+\+ Statistics Dump \+\+\+/{print strftime("%Y/%m/%d %H:%M:%S",$2)}' named.stats
# もしかすると strftime() は GNU awk だけでしか使えないかも…
ところでなんでperlなの?
python: ワンナイナーの敵
awk: 実装が沢山あり、動作が異なる場合がある
r***: 論外
rexx ?
なんで論外なの?
165 :
名無しさん@お腹いっぱい。:2014/01/25(土) 14:49:39.47
>>157-160 そんなに早くレスを頂けるとは思っておらず、お礼が遅くなりました。
ありがとうございます。
そうか。awkやperlでgrepと同じことが出来るんですね…勉強になりました。
167 :
名無しさん@お腹いっぱい。:2014/01/28(火) 22:58:27.17
変数$aaaの中身を右寄せし、半角スペースを5つ付けて合計10桁の固定長にし、これを別の変数$bbbに代入した場合にちゃんと10桁にするにはどうすればよいですか?
>>149 待て待て、gnu dateなら複数行入力の一括変換とか出来るぞたしか
>>167 昔、似たようなことをやりたくて探したことがあるけど…
あきらめて${#aaa}とかで文字数をカウントして、欲しい桁数からその数値を引き、
付け足すべき半角スペースをループで作って継ぎ足しただよ。
例外処理とかめんどくさかったので、いなかもんのおらも知りてぇだ。
170 :
名無しさん@お腹いっぱい。:2014/01/28(火) 23:51:39.80
>>167 レスありがとう。
やはり、ループで足すしかないですかねぇ。
#!/bin/bash
aaa="hoge"
bbb="$(printf "%10s" "$aaa")"
echo "$bbb"
IFSいじっちゃえw
ふつーに
>>171だろ。
printf(1)とか、シェルのクオーティングの振るまいとか、
基本なので理解しとくべき。
いやいや、GNU date を使うやり方。
>>175 すまん、たまたまかなり新しいバージョンのdateだった8.15
-fでファイルを読み込める。
バージョンいくつから出来るのかは知らん
「str表示すらできないHP-UXのdate」って書いてあるしGNU dateじゃないんじゃないの
FreeBSDのdate確認したらファイル読み込んで1行ごとにって機能はなさそう
入れるだけじゃん許されるならばだけど
許されないほうがなんかきもちいい。
181 :
名無しさん@お腹いっぱい。:2014/01/30(木) 22:10:02.56
hoge="(株)ほげほげの売上は%1です。"
の%1をsedで置換したいのですが、(でエラーとなってしまいます。
特殊記号の()を読み飛ばして置換するにはどうすればよいですか?
>>181 " " ではなく ' ' でくくるといい
一生に一度くらいは入れてみたいものである。
185 :
名無しさん@お腹いっぱい。:2014/02/03(月) 21:48:36.77
シェルスクリプトにてSQLの結果をメール送信するプログラムを作ろうと思います。
以下のようにやると$resultの結果が取れないのですが、どのようにしたらよいでしょうか?
sendMail() {
from=$1
to=$2
inputEncoding="utf-8"
outputEncoding="iso-2022-jp"
subjectHead="=?${outputEncoding}?B?"
subjectBody="`echo "$3" | iconv -f $inputEncoding -t $outputEncoding | base64 | tr -d '\n'`"
subjectTail="?="
subject="$subjectHead$subjectBody$subjectTail"
contents="`echo -e $4 | iconv -f $inputEncoding -t $outputEncoding`"
echo "$contents" | mail -s "$subject" "$to" -- -f "$from"
return $?
}
PSQL=`echo -e "\
〜〜〜SQL文〜〜〜
`
from="
[email protected]"
to="
[email protected]"
subject="件名を入力"
contents="SQLの結果"
result = echo "$PSQL" | psql -U hogehoge
contents=”結果です"
sendMail "$from" "$to" "$subject" "$contents$result"
>>185 > result = echo "$PSQL" | psql -U hogehoge
result =$( echo "$PSQL" | psql -U hogehoge)
187 :
185:2014/02/04(火) 13:38:46.35
>>186 ありがとうございます
しかし、それだと改行がされないんですよね
A 152
B 585
C 209
と出したいところが
A 152B 585C 209
のようになってしまいます
>>187 こんな感じ?もっといい方法ないのかな
echo "$PSQL" | psql -U hogehoge | while read line;do
result="$result\n$line"
done
シェルでやるよりperlか何かでやる方が楽そう。
>>187 規制くらってたわ。
改行を保持したいのなら、引数でわたすのではなくsendMailの標準入力に渡したほうが楽だろ。
echo "$PSQL" | psql -U hogehoge | "$from" "$to" "$subject" "$contents"
にして、sendMailのmailコマンドを
{echo "$contents" ; cat - } | mail -s "$subject" "$to" -- -f "$from"
のようにして呼べばいい
191 :
185:2014/02/04(火) 21:26:43.93
ありがとうございました!
シェルでやれる範囲を超える場合はperlって人多いみたいけど、python派が少ないのは何でなの?
世の中的には最近やたらとpython流行ってるじゃないですか
シェルスクリプトって one linerで書いてテストしながら組み合わせてく
ってよくやるけど、pythonは多くの構文が改行を要求するので、ふだんと
違う改行なしの書き方使うことに
なって違和感があるとか?
まあクオートの中に改行入れられるから、そうするって手もあるんだけど、
シェルによっては編集が不便になるし。
echo $(( $RANDOM 55555 ))で55555までの乱数が出せますが、
55500から55555までと規制したい場合はどのようにすればいいのでしょうか?
echo $(( (RANDOM % 56) + 55500 ))
なるほど、そんなやり方があったんですね
参考になりました
>>192 pythonは正規表現の使い勝手が良くないのとワンライナー書くのが実質的に無理
198 :
189:2014/02/08(土) 11:22:11.44
perl以外でやっても別にいいよ。
だから「perlか何か」と書いている。
199 :
189:2014/02/08(土) 11:28:02.40
perl使う人が多いのは
歴史が古いってのと他に乗り換える理由がないってだけじゃないかね。
ワンライナーにこだわる必要はないし、
いきなりpythonスクリプトのファイル書き始めても別にいいんじゃね。
好きな言語で好きなように書けばいい。
>>196 それ自力で思いつかないとすると、相当センス悪いよ
$RANDOMってたかだか 0〜32767 の値しかとらないから、
% 56 とかで剰余とったら値が小さい方に偏るから一様乱数にならないよ。
% 64 とか、2^n で剰余とった上で、値がはみ出した場合は再試行する方がいい。
おおおおそういうことだったのか俺のバカ野郎!
横からだけど、ありがとう201さん!
>>201 俺は言ってることがわからんけどw
コードでいうとどういう事?
>>203 while (((i = RANDOM % 64) >= 56)); do :; done; echo $((i + 55500))
>>204 じゃぁ今思い付いたけど、ポート番号なんかのように数が大きい場合はどうするの?
49152–65535が自由に使えるけど、以下の場合は{$NUM}はどうするの?
while (((i = RANDOM % {$NUM}) >= 16384)); do :; done; echo $((i + 49152))
16384は2^nだけど、となるとi = RANDOM % 16384のままでいいの?
というか、
echo $(( (RANDOM % 16384) + 49152 ))
のままでいいと言うことになるのかな?
そういうことでしょ
2^nなら一様乱数になるんだから
209 :
名無しさん@お腹いっぱい。:2014/02/08(土) 22:09:57.81
シェルスクリプトで実行したコマンド結果の標準出力、標準エラーをログファイルに出力するにはどうすればよいですか?
command > log.log
とひとつづつ書かないとだめなのでしょうか。
#!/bin/bash
exec 1> log.txt
exec 2>&1
echo hoge
echo fuga >&2
ファイルにも標準出力にも出したい時は
exec 1> >(tee log.txt)
>>209 スクリプト内のコマンド実行結果すべての標準出力/標準エラー出力を
まとめて同じログに送っていいなら、スクリプトの結果をリダイレクトすればよろし。
$ script.sh > log.log 2>&1
細かく制御したいなら、
>>210 がよろし。
>exec 1> log.txt
>exec 2>&1
なんで2行に分ける? basherは頭が悪いな
exec 1> log.txt; exec 2>&1
こうか?
xec >log.txt 2>&1
これかね 引数の順番を逆にすると駄目
basherとかひとくくりにされてもな。
バッシャー板前
シェラー同士仲良くしろよ
ゼットエスエッシャー
今日も元気にシェルでワンタイマーしましょう
>>215 > #!/bin/bash
こういうおバカはひとくくりでかまわない
>>220 >>210 の最終行で named pipeの文法使ってるから #!/bin/bashにする必要がある。
#!/bin/sh で起動すると(たとえ実体はbashでも) sh互換モードになって named pipeの文法がエラーになる。
>>221 bash固有機能は使うなよ
ということを言いたいのでは?
>>222 使ってもいいじゃん、と言いたいのでは。
tcsher涙目
・・・きっともう、シェルスクリプトはshやbashで書くtcshユーザも肩身が狭いんだろうな・・・
zsherも忘れないで
fisherさんかっこいい
てっきり#!/usr/bin/env bashって書けって話しかと思ってた
228 :
名無しさん@お腹いっぱい。:2014/02/12(水) 21:51:15.94
tcsh使う奴死ねと言われてからもう10年はたつだろ
もはやtcshユーザなんてどうしようもない偏執狂しか居ないはずだが
HP-UXとかAIXとかはcsh標準らしいが
絶対使いたくないわ
>>228 ホントスンマセン。by tcshユーザー
スクリプトは勿論Bourneシェルで書くんだけどねえ。
そもそもHP-UXとかAIXとかいまさら使いたくない。
>>230 それならいいんじゃね。
スクリプトのスレなんだから。
>>232 あんがと。
企業で稀に見かけるcshスクリプト書きって、偏執狂というより
単なる物知らずって気がするよ。
bash登場以前、newcshとかあった頃は、対話的シェルはcsh系が
主流で、よく分かってない人の中には、なんとなくスクリプトもcshで
書くって人がいた(俺はその頃からスクリプトはBourneシェルだったけど)。
で、その頃に書かれたスクリプトを秘伝のたれみたいに直し直し
使ってるのを2000年頃に見て驚いたことがある。
俺のまわりでは、そういうのもさすがに滅んだけど。
>>233 企業とか大学とかでもまだ見るよ、代々cshスクリプトをなおすところ。
基本 csh しかわからない人しかいないから sh に移行できない/しても指導できる人が居ない。
235 :
224:2014/02/12(水) 23:00:07.35
>>230 同じく
つってもプロンプトを移植するのが面倒でtcsh使ってるだけのニワカだけど・・・
俺も2000年ごろにcshスクリプトに遭遇したな
ログインシェルもcsh系だった気がする
今となってはcshしかわからない人なんていないでしょ
わざわざコストをかけて書き直すほどのものじゃないって
そういやFreeBSD鯖のログインシェルはtcshのままにしてるな
デフォルトから変更するほどシェルに思い入れが無いだけかも
bashのスクリプトを標準出力に吐き出すスクリプトを作ったのですが、この結果を一時ファイルに保存せずに
そのまま実行する方法があったら教えてください。
吐き出すスクリプトは具体的にはffmpegを複数行実行するものです。
bash -s とかやってみたのですが、うまくいきませんでした。
>>237 echo ls | bash -s
とかで動くけど? (この場合は -s は省略可)
>>221 >
>>210 の最終行で named pipeの文法使ってるから #!/bin/bashにする必要がある。
「named pipeの文法」ってなんだよ
これだからbasherは… w
>>237 /dev/nullにリダイレクトしては駄目なの?
242 :
237:2014/02/13(木) 12:55:37.44
>>238 そのやり方ですと、1行目で実行したffmpegが2行目以降を
キー入力として受け取ってしまうようなんです。。。
一度リダイレクトでファイルに出して、
bash tmp.sh
みたいにすれば問題なく逐次実行されます。
よく分かってないのですが、標準入力とttyの関係とかでしょうか
>>242 ffmpeg </dev/tty
みたいにして、キー入力を端末に強制する方法と、
bash <(スクリプト)
みたいにして標準入力を使わずに済ます手がある。
だが、最初にキー入力の問題だと、ちゃんと書くように!w
244 :
237:2014/02/13(木) 14:38:09.52
>>243 どちらの方法も完全にうまくいきました、ありがとうございました!
後者のやり方がなぜうまくいくのかまだピンときていませんが、
いろいろ調べてみようと思います。
あと最初からキチンと書かなくてすみませんでした
246 :
237:2014/02/13(木) 17:03:46.98
>>245 なるほど、こういう機能ってzshにある感じはしていたのですが、
bashにもあるんですね!
bashの ( ) はサブシェルだと思っていました…
確かにzshにしかない機能と思ってたのがbashにあって驚くことあるな
少しずつ入れてんのかね
入ってるね。
個人的には {1..30}が入ったのは地味に大きい。
それでもzsh使ってるけど。
ヒストリの共有(share_history)が bash にも欲しい
日々使うインタラクティブシェルとしてはzshが良いけど
バッチ処理させるスクリプトとしてならbashの方が使いやすい
というかzshは機能多すぎドキュメント多すぎで訳ワカメ
スクリプトでもzshにしてる
どの機能がbashがサポートしてるか調べるのめんどい
zshは.zshrc等をてんこ盛りにしてると、zshスクリプトが読み込みに超長時間かかる
かといって #!/bin/zsh -f にするとめちゃ使いづらいし・・・痛し痒し
zshはバグ多い。
#!/bin/zsh
echo hoge >file1 >file2 >/dev/stdout
↑これだけで固まるw
zshでスクリプト書くぐらいならperlでいいじゃんと思う
>>138 ConnectBot、メモリ食い杉だ。他のシェル端末の方がいい。
どうみてもバグだった
社史編纂室くんの出番や
編纂の「纂」の字書ける人どんくらいいるだろう
chassisのスペルと発音ちゃんと覚えてる人どんくらいいるだろう
chassis hen sun shits
初めてbashでスクリプト組んでるんですが、
. ./hoge.sh fuga.txt
みたいに引数渡して起動してるシェルを、引数変えて再起動するにはどうすればいいですか?
シェル内で
. ./hoge.sh $fuga
みたいに変数いれたらダメで、
. ./hoge.sh fuga2.txt
みたいに指定したら行けます。
なんでsourceするの? ちょっと間違うと無限sourceループになるよ。
>>265 その $fuga というのがスクリプト起動時にはまだ値がないんだろ? それなら駄目。
hoge.sh の中で fugaに値が代入されるとしても、それを起動時に指定することはできない。
>>266 同じ構成の画面を、設定ファイルを指定して使い回すためです
>>267 ありがとうございます。
テキストにでも書き出して、そこから読み直してみます。
>>267 だから、なぜ普通に起動せずにsourceで実行するのかを聞いてるんだが。
>>268 init.dとかのスクリプト見て真似てみたら。
関数にして呼び出す。
普通に出来るけど
$ cat hoge.sh
echo "hoge.sh is called with $1"
if [ "$1" = "fuga.txt" ] ; then
fuga="fuga2.txt"
. ./hoge.sh $fuga
fi
$ . ./hoge.sh fuga.txt
hoge.sh is called with fuga.txt
hoge.sh is called with fuga2.txt
272 :
265:2014/02/20(木) 09:12:57.78
みなさんありがとうございます。
どうやら変数の入れ方の様です。
fuga.txtに
trans_2=fuga2.txt
があって、
read input_key #ここで2を入力
eval input_trans='$trans_'input_key
echo $input_trans
これで
fuga2.txt
と出力されるのですが、
. ./hoge.sh $input_trans
とすると、引数を読まない感じです。
直前に
$input_trans=”fuga2.txt”
といれると動きます。
端末から直接書き込めないので、スマホで打ってるので、
読みにくくて申し訳ないです。
なんでman見ないんだ?
. にはオプショナル引数は渡せない。無視される。
>>271 basherは「普通に」と言うな
274 :
265:2014/02/20(木) 13:03:57.32
>>273 なるほど。ありがとうございます。
manはききませんでした。
cygwinなので、インストールをスキップされてるのかもしれないです。
>fuga.txtに
>trans_2=fuga2.txt
>があって、
もしかしてfuga.txtもsourceする?
そこに原因がある気がする
>>273 でも、今は「普通=bash」だから仕方ないですよね・・・
ログインシェルとシェルスクリプトシェルを混同すんな
ログインシェルならtcshユーザだってそこそこ居るんだぞ
さすがに今はいないよ
そもそもtcshがまだ存在するということに驚くというか
動いているところを見たことはない
冬だからな
>>278 俺 csh なんだけど…。
実体は tcsh の csh モード。
そもそもみんなログインシェルは
何をきっかけに乗り換えるものなんだ?
俺にはまだきっかけが来ない。
>>282 俺は最初に与えられたのが tcsh で、暫くそれ使ってたが、人の書いたシェルスクリプトを修正したり
しているうちに sh の文法の方が詳しい状態になったから bash に移行したわ。
部屋の模様替えみたいな気分でやってみればいいんじゃね?
ふと思いたってbashからzshに乗り換えた。今ではもう戻れない
csh->tcsh->bash->zsh->csh
堂々巡りでもうどうでも良く
なんか俺は多分 csh の全機能の 10 分の 1 くらい
しか使ってないだろうから、csh は機能が足りないと
か不便だとか言えなくてなあ。
.cshrcが50kBもあるw
このスレ、この板にいてなおcsh使いがいるとか・・・tcshならともかく
自分で使う分には勝手だけど、くれぐれも後輩に広めんなよ
ログインシェルとしての欠点を教えてくれ
欠点って.cshrcがcshスクリプトだから.cshrcのカスタムに拘ると死ぬくらいじゃねーの?
実行結果の違いでも出して論じてくれるなら見てて楽しい
でも、そうでないなら・・
cshって補完機能をカスタムできるんですか?
うーん?cshもけっこういろいろあって、オリジナルのcshはかなり低機能だったけど、
最後にみたcshは補間機能とかけっこう充実してた記憶が
>>293 すいません、csh系のシェルについて聞いたつもりでした。
tcshとかだとできるんですかね?
ログインシェル云々の話が出てるけど、ログインシェルを普段使うシェルとは
別ものにしてる人っていんの?ログイン後にわざわざ切り替えてんの?ありえねー
俺なんか$HOME下にビルドした最新のzshを躊躇なくログインシェルにしてるわ
>>290 stderrだけをリダイレクト出来ない
foreachを1行で書けない
>>295 zshのログインシェルでviをたちあげcshスクリプトを書く、とかそういうことじゃないの
chshでシェル変えちゃうとそのシェルがないときにログイン不能になるから
.bashrcに/usr/bin/zshって書くべし
みたいなことをFreeBSDのマニュアルかなんかに書いてた気がする
俺は/etc/shellsにzshがないから仕方なくcshrcにexec zshしてる鯖があるな
>>295 俺は毎日他社の違うサーバにrootアカウントで入る日々だから
ログインしたら1発目のコマンドが
# /bin/csh ; exit
だ。
元のログインシェルが何か調べもしない。
OSの素性を調べるのもそれから。
そのあと好みの環境変数等を全部手打ちして
それからOSの素性を調べてから作業に入る。
今どきLinux系なら/bin/cshがないことも多いと思うけど
あと/bin から /usr/bin に移行しつつあるし
>>301 # exec /bin/csh でいーんじゃないの
chshが存在と/etc/shellsの確認するだろ
NIS使ってるときとかの話じゃね。
あるマシンでchshした後別のマシンに入ったらうんぬんとか。
>>301 cshがデフォルトでインストールされてる環境ってどこのやつ?
ちょっと気になったので雑学として聞いておきたいです
手元のマシンだと /bin/csh は
CentOS, FreeBSD -> ある
Debian, Ubuntu, Arch, Gentoo -> ない
だな Debian は minimal から構築したもので Ubuntuはサーバ版
CentOSはVPNとして借りてるものだから俺がセットアップしたのではないが
とてつもなく古い製品で無ければ、
(正統な意味での)UNIXのライセンスを受けてるUNIX系のOSならば、
ほぼcsh入ってるんじゃないかな
310 :
301:2014/02/21(金) 20:49:22.89
>>307 RHELとSolarisがほとんどで
他はだいたいCentOSかFreeBSDかUbuntu。
/bin/cshが無いOSがあるって
まだ気づいてなかった。
まあ会社のサーバなら管理者が
そーゆー人のためにcsh入れておいてくれるだろうね
>>304 現在稼働しているあらゆるUnix系OSではzshがデフォルトでインストールされてるの?
>>308 デフォルトでインストールされてるかの答えになってなくね。
>>313 zshのことなら、ない環境一杯あるでしょ。
RHELあたりでも、ミニマムだと入らないはず。
いわんや商用UNIXをや。
>>302 ん?/binがないってこと?
シェル系が/usr/binに移ったってこと?
>>314 商用UNIXだと入ってないことがスパコンで何度もあったよ
去年某大学の共用スパコンでも入っていなかった
>>316 スパコンとかこの手の環境だとよくあるね
下手するとcsh推奨とか言い出す
死ね
318 :
316:2014/02/22(土) 00:16:16.51
>>317 csh推奨というかtcshなしbashなしで
sh,csh,kshしか入ってなかった前の職場orz
そりゃ、商用UNIXの製品にオープンソース系のコードをほいほい取り込めないからなあ。
sh、csh、kshあたりは商用UNIXのコードに標準で取り込まれてるんだよ。
320 :
316:2014/02/22(土) 00:40:44.56
>>319 それは分かってるんだけど
/usr/localや/optなんかにソフトが大量に入ってるのに
シェルだけはインストールしてくれないんだよ
頼んでもその三つを使えってことで
コンパイラあるんだったら自分でビルドするのはどうなんだろう
あーでも癖のある商用UNIXじゃbashやzshのビルドは難しいのかな
>>321 bashやzshだけのビルドはうまくいかなかったおぼえがある
ビルドの失敗だけじゃなくで実行時にfatal errorとか
GNU iconvみたいな依存するライブラリも含めてビルドすれば問題なかったけど
コンパイラ自体がそれらのコードを受け付けない場合も辛いが、
自分でビルドってのはその辺の面倒まで見ることを言うんじゃね?
>>315 Solaris とかは /bin は /usr/bin へのシンボリックリンクだね。
イマドキは /system/bin/sh だったり、、
>>324 「Debian,Ubuntu,Gentoo,Archはない」って書いてあるのでは?
>>325 Archも/binと/sbinが/usr/binになってるな
/binが/usr/binのシンボリックリンクになってるのは過去の互換性というか
#!/bin/bash って書いちゃってるスクリプトへの対処療法的な措置だろ
>>330 そんなおまぬけの救済なんてしなくていいのに
しかし
#! /usr/bin/env bash
だとPATHに自分でコンパイルしたbashとかあった時にそっちが実行されちゃう罠
$ type env
env is /usr/local/bin/env
bashも/usr/local/binへインストールされているのがおにあい。
FreeBSDでは実際/usr/local/bin/bashに入るしね
#! /usr/bin/env PATH=/bin:/usr/bin:/usr/local/bin bash
>>328 嫌なら rm /bin しとけばいいんじゃね。
rmは怖いからunlink使うことにしてる
ミッションクリティカルな分野とかスパコンとかでも、徐々にLinuxが浸透しつつあるし
商用Unixが駆逐される日も遠くないだろうな
そのときは晴れてシェルがbashとzshに統一されるわけだ
bashはGPLだしそのあたりがまずいこともあるはず何だよな。
ところで、/usr/binって、/binへ移行していく風潮なかったけ?
その話を見たとき、数年後にはまた、パス関係ではまるのかーと少し意識した記憶がある。
少なくともFedoraとArchは逆だな
最近/binがなくなって/usr/binになった
一応シンボリックリンクとして残っているけど
>>341 基本は /usr/ 以下に移そう、ほんとに必要なのだけ / 直下に置こう、
っていう方向じゃないの。
rootが何かしないと変更されないものはusrだっけ。usrをnfsでmountする時はどうするんだろ。
その辺はFHSでも読んでくれ。
FHSだとNFSまでの最低限は/binに入れるだったのでは。
/sbin/sh がないので /sbin だけじゃ NFS マウントできないのでは?
solaris は /sbin/sh があるので可能だけど。
>>348 > /sbin/sh がないので
それどのOSの話?
>>349 たいていの OS。
起動時に NFS マウントするためのスクリプトが #!/bin/sh で書かれているので
/bin は少なくともローカルになければならない。
solaris はそうなっていないので、/sbin だけローカルにあれば /bin も NFS に置ける。
というか、/bin -> /usr/bin の symlink だけど。
>>350 > 起動時に NFS マウントするためのスクリプトが #!/bin/sh で書かれているので
それ思い込みじゃね?
手元のUbuntu見ると、確かに/sbin/shは無いな
何故無いんだろう。まずいことでもあるんかな
/etc/fstabに書かれたNFSなどは初回は無視されて、それマウントするのがinit.dのnetfsとかのシェルスクリプトだっけか
確かUbuntuでnetfs自体行方不明だったから仕方なくrc.localだかにmount -aを書いた覚えがあるけど、
最近はその手の初期化周りを制御するinitdを置き換えるlaunchdとかも出てきてるし今はどうなってるんだろうな?
もういいかげんスレ違いじゃね。
/sbin/shは昔はもっと意味があったのだよ
今は/usr何かを別のファイルシステムでマウントするとかほとんどないからな、さして重要な意味がないのでlinux何かでは一緒くた。
solarisでも今は形骸化してる。
/binだけローカルにあったって、実行できないんだぜ?
>>343 ありゃ、逆でしたか失礼。
シェルの先頭で変数に入れちゃうから、かわってもそこを変えるだけですむようにはなっているのですがね。
バージョン違いでパスがかわるとめんどうだなぁ。
357 :
名無しさん@お腹いっぱい。:2014/02/25(火) 01:17:07.19
シェルで@はOKですが、AがNGです。 シェルの中でfindコマンドは*(アスタリ スク)は使用できないのでしょうか? echoで表示は出来ているのですが。。。
# @ これはOK
find /log/*/*/*.log -type f
# A これがNG
set target="/log/*/*/*.log"
echo ${target}
find "${target}" -type f
引用符外してみたらどうでしょ
target='./log/*/*/*.log'
echo "$target"
find ${target} -type f
setって何だよ
cmd.exeっていうシェルの環境変数設定コマンド
これが社史編纂室系か
社史を編纂しながらシェルスクリプトを作っていく、か
どうすればそんなうらやましい立場になれるんだ
>>355 うちのDebianの/binで調べたら、/usrにリンクしてるのは、ping6だけだった。普通、/libに入れるんじゃないか。
オレあと3年で定年だから社史編纂室みたいなところで平穏無事に時間だけ早く3年経って欲しいわ
>>364 老い先短いんだから平穏無事はともかく時間を急いては勿体無いですよ、先輩。
366 :
名無しさん@お腹いっぱい。:2014/02/25(火) 17:27:12.85
bashで、メールが来た時 You have mailって出ますよね。
これを、特定の相手からのメールのみ表示するとか、相手によって表示メッセージ変えることとかできますか?
できません。
bashじゃなくてもいいんですが、メールが来た時 You have mailって出るのを、
ウェブメールにも対応させることってできますか?
できません。
bashかzshで、ウェブサイトにhttpsでアクセスして、
認証させて、ページ内容のHTMLを取得して、
解析したり加工したりして前回との差分を取る関数を作って、
その結果でプロンプトを変えることはできますか?
できる
優しいやつめ
できるとは思うけど、ネットの都合によっては、
プロンプト出すたびに10秒とか1分とかかかりそう。
バックグラウンドで数分おきに監視して、
ファイルに蓄積していくとかすればいいのかな。
bash で書いたスクリプトって、そのままでzshでも動きますか?
とりあえずword splitでハマる
posix準拠のみの機能しか使ってなければ大丈夫
posix準拠のみの機能しか使ってなくてもword splitでハマる
zshってcsh並に絶滅寸前だよね・・・
いっしょにすんなw
ビル・ジョイに失礼だ。
すみませんでした
cshはまだまだ減益ですね
いいえcshが原液だったことはありません
1
ターミナルから青空文庫など文章サイトの特定のhtmlにアクセスして、タグを除いた文章のみを抽出し、それをテキストファイルにして保存。
(出来ればそれをTeX文書にして、事前に決めた設定でPDF出力)
2
ターミナルから音楽視聴サイトなどのhtmlにアクセスして視聴できる曲のタイトルを抽出したのちプロンプトに表示。
その後入力を促し、入力に応じてプレイヤーで特定の曲を聴く、もしくはなにもしない。
(そのサイトではタイトルからmp3のurlが推測可能で、タイトルさえ取れればいい)
ということをやるために勉強をしたいのですが、
こういうことをやる為にはシェルスクリプトを勉強すれば大丈夫ですか?
それともCとかPythonとかPerlとかを勉強した方がいいですか?
ちょっと質問いいですか
if文でこんなふうに x とかの文字を挟むスクリプトをよく見かけるんですが
if [ "x$hoge" == "xYes" ]
なんでこうするんですかね?普通に
if [ "$hoge" == "Yes" ]
じゃまずい場合があるとか?
>>383 htmlのパーサはbashじゃちと辛いからPerlとかPythonとかが一番向いてると思う
その用途ならCは要らんな
>>385 ありがとうございます。
いずれにしろ使える知識なので少しは勉強するつもりですが
上の目的の為にはPerlかPythonを使います。
>>384 $hoge に空白が入ってきた場合や何も入っていない場合に
if [ "$hoge" == "Yes" ]
だと
if [ == Yes ]
こうなり、
if [ "x$hoge" == "xYes" ]
だと
if [ x == xYes ]
こうなる。
なので、
ワロタw
>>387 変数をダブルクォートで囲ってあれば、xとか前につけなくても平気じゃないの?
昔、つけないとヤバイ場合があった記憶があるんだけど思い出せない
俺は "-x" のようにハイフンで始まるとオプションとして扱われるからだったような気がするけど
手元で試したら普通にハイフンで始まっても大丈夫だったな
あと [ ] 内って == 使えたっけ?
うちの環境だと
/usr/bin/[ は == がOK
bashの組み込みの[も == がOK
sh(dashだった)の組み込みの[は == がNG
393 :
384:2014/02/28(金) 23:21:24.48
>>387 いや、
>>389の言う通り、普通は未定義変数でもダブルクォートしてれば空文字扱いになるよね?
おそらくそうはならない環境のための配慮かと思ったんだけど・・・
誰かこの辺詳しい人いません?
>>394 おードンピシャなページですわthx
なるほど、[ がビルトインじゃない時代の互換性のためだったのね
じゃあ今の時代では必要なシーンなんてほぼ皆無だろうね
未だに if [ "x$hoge" = "xYes" ] とか書いてるプログラマーorシス管見つけたら
社史編纂室に異動させるわ
既存ファイルの特定文字列にマッチした行の下に、任意の文字列を挿入する一般的な方法ってないですか?
ここで言う任意の文字列というのは、$'"/などの記号文字や改行も含む複数行から成る文字列です。
できれば
str="
文字列1
文字列2
・・・
文字列n
"
というstrを作った上、sedなどで一発でできればいいのですが。
>>395 ビルトインでない [ はビルトインの [ を持っていないシェルのために存在するものちゃうの?
将来的には消してビルトインの方に統一するんちゃうの?
やったら逆やと思うんやけど。
400 :
名無しさん@お腹いっぱい。:2014/03/01(土) 16:45:16.38
>>398 sed '/hoge/a --foo--\n--bar--' -i file
ここのスレレベル低いから質問しても知ったかのバカが適当に答えてるだけだよw
見ててわかるからおもろいw
と、低レベルがうなってます
>>400 変数strを使う場合はどうですか?
sed '/hoge/a $str' -i file だとstrの中身が返らないし
sed "/hoge/a $str" -i file だとエラーになるんですよね。
結局strの中身の特殊文字をうまくエスケープしておかないと駄目みたいで、面倒だなぁと前から思ってまして。
別にsedに拘っているわけではないです。とりあえず今はこんなふうにして凌いでいます。
cat > file2 <(sed -n "1,/hoge/ p" file) <(cat << EOF
文字列1
文字列2
・・・
文字列n
EOF
) <( sed -n "/hoge/,$ p" file | tail -n +2 ) ; mv file2 file
いまいちカッコ悪くて気に入りません。
それに file が巨大な場合は2回sedをかますのは非効率的だろうし。。。
この手の挿入処理はよくあるテクだと思うので、他にもっと良い方法があるんだろうと思ってたのですが。
sedが駄目ならawk使えば
hoge='ho$ge
fu/g"a
piyo'
echo "apple
banana
orange" | awk -v hoge="$hoge" '{print}/banana/{print hoge}'
>>404 おぉ、そんな方法が!awkに変数をまるっと渡せるのがミソですね。
ありがとうございました。
shでechoの出力先をデフォルト標準出力、ファイル指定されてたらそのファイルと言うことをしたいのだけど。
/dev/stdoutがsuした後だと使えません。
出力先が指定されているかいないかで分岐して同じechoすればいいだけなのだけど、
分岐なしでいけるクールなやり方ありませんか?
良く分からんが exec 1> file とかじゃ駄目なのか
>>398 「できれば」以降がよくわからんけど・・・
Perlで全文読みきって正規表現で置換するワンライナー書けばいいと思う
Perlの正規表現なら改行文字を含んで複数行のマッチが書ける
sedでも出来る気はするけどsed使うの苦手なんで他の人にパス
>>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
あー
>>404さんの方法、マッチする/banana/の部分も変数で渡したい場合は駄目でした。
/ /の中身は正規表現で解釈されちゃうからエスケープが必要ですねorz
hoge2='hoge$hoge'
echo "apple
banana
orange" | awk -v hoge="$hoge" -v hoge2="$hoge2" '{print}/hoge2/{print hoge}'
>>408 「できれば」というのは、挿入したい文字列をそのままの形でスクリプトに書いておいて、
その後の挿入処理もsedなどで華麗にワンライナーで書きたい、という願望です。
perlならできるのでしょうか。ゴミみたいな知識しかないので少し勉強しなきゃ。。
>>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は行マッチの / / が正規表現ではなく固定文字列というのが、この場合丁度良かったということですね。
>>411 一つ補足します。
sedに渡すための searchLine に / が含まれるとsedでこけてしまう。やはり万能ではないか。。。
というかこの手の処理を完璧に汎用的にするというのは、もしかして不毛な考えなのでしょうか。
さらにおまけの補足ですが、
>>404さんのようにechoの標準出力を
>>411のsedへ渡す場合は、
そっちも/dev/stdinだと解釈されてしまいますね。本筋の話ではないですが。
413 :
408:2014/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なら環境変数にさえ値を入れられれば問題なく処理できるかとー
テストコード貼ろうかと思ったけどヒアドキュメント版は改行多すぎぃ!
ここでは関数使ってブラックボックスにするのはアウトなんですか
どうしようsedとAWKとPerl
Perl覚えたらsedとAWKでできるテキスト処理できるらしいじゃん
ワンライナーだけでも覚える価値あるかな?
sedは s/hoge/fuga/ が用途の99%占めてるし
awkは {print $2} が用途の99%占めてるから憶えるまでもない
それを越える複雑な処理したい場合は素直にperlとか使うべし
最近はxmlstarletも便利だけど、webだとパースできるページ少ない。
>>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
て感じでどうだろう
>>407 指定されてたら複製させる感じか。
明日試してみます。
>>413 perl使うのなら
BEGIN{undef $/;} s/(??Q${検索文字列}?E)/$1${挿入文字列}/g
とかじゃダメなん?
>>413,418,420
ありがとうございます。
perl全くの無知なんで勉強してみます。
# perlってなんか独特で敬遠してたのよね。。。sedやawkでできない場合に困るし、やっといたほうがいいな
perlはもう10年書いてないけど困ったことはないな
rubyとpythonが書ければ何とかなる
/usr/localのインストールは禁止されてるので、perlはあり得ない。
普通に sed awk あるいはシェルのみで書く。
僕はnode.jsでいいです
>>420 ダメじゃないと思うぞ、プログラム全般がそうだけど、Perlは特にTMTOWTDIとかいう標語まであるし
俺はそのやり方で\Eとか含んでても大丈夫って知らず、エスケープに悩みたくなくてああしただけ
>>423 そういう環境ならそうだけど…
そういう環境って組み込みとか起動中処理とかそういうケースだけのような気も…そうなるとsed awkも怪しい気がしなくもない
最近はLinuxならperlはもちろんruby、pythonも入ってるのは当たり前なんだっけ?
>>426 デフォルトでぜんぶ入ってるのは少ないんじゃないか
FreeBSDで適当にPorts入れようとするとRubyやPython要求される
(つまりその時点では入ってない)ことが結構あった気が…Perlはどうだっけ
m4もいれといて
430 :
名無しさん@お腹いっぱい。:2014/03/03(月) 03:46:25.79
ruby入ってない@deb
俺のイメージだと入ってる可能性が高い順に
python,perl,rubyだな
python,perlは入ってるな大体
>>434 15年前には入っていたけど最近のバージョンには入っていないのか?
もしかしてperlはもう消えていきつつあるソフトウェアなのか?
perlが消えていくってことは(今のところは)ないけど、
perl以外の選択肢は増えている。
perlよりワンライナーが有用な言語ある?
rubyやpythonかじったけど、普段のデータ処理は結局perl使ってるなあ
基本だけ知ってれば、いちいち調べなくても書けるのがいい
>>434 NetBSDにもperlはない。
luaはあるが。
luaなのは、組み込み言語用途での実績かららしい。
>>436 その記事だとカーネルビルドに必要なくなっただけでデフォルトインストールだと書かれてるけど…
つーか、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
最近猫も杓子もpythonな風潮が気に入らない
>>443 シェルスクリプトと言い張る。
#!/bin/sh
python -c hogehoge...
EOF
>>444 pythonなら
#!/bin/sh
python <<EOF
hogehogehoge
EOF
にしないとワンライナーで書くことになって死ぬ
冷や毒は添付ファイル作るから、/tmpが書き込み不可(boot時など)の時動作しない。
豆な。
当て字きもい
そんなあなたに冷やすとリング
2ch とはいえ技術系スレだもんな。
技術系スレとはいえ 2ch だもんな。
どっちが大勢?
そういうのは別のスレで。
そういう詰まらんオマエは別のスレへ。
>>446,448 みたいな当て字書くプログラマーorシス管見つけたら
社史編纂室に異動させるわ
当て字に塗れた社史とか読みたくないです
>>448 冷やすとリングも添付ファイル作るから解決にならんよ。パイプで書き換えること。
455 :
名無しさん@お腹いっぱい。:2014/03/06(木) 00:46:35.73
cshでは以下のようなことはできないのでしょうか。
set usage="usage : `basename $0` -hoge [A|B|C]"
[]でエラーになります。
>>455 >>1 > ・csh/tcshのシェルスクリプトは推奨されません。
> (理由は「csh-whynot」でググれ)
ログインシェルとして使うのはともかく、スクリプトにcsh系を使うべきではない
社史編纂室に異動させてほしいです。
仕事なくても養ってくれるなんて、今どきあり得ない好待遇じゃないですか。
左遷される前にクビが飛ぶんですから。
そのかわり人格破壊作業を施されるとか
社史や社史編纂室を作る余裕があるような会社に就職したいです
>>455 使ってないけど、
set usage="usage : `basename $0` -hoge "'[A|B|C]'
じゃダメなの?
PS1やエイリアスを指定した状態でbashを起動し
対話操作できるようにできますか?
bashをヒアドキュメントを利用して起動してもbashが終了してしまい-cオプションでも同じことが起きます
-o ignoreeofでもダメでした
>>461 環境変数だけなら env PS1="..." PS2="..." /bin/bash でいける。
別途ファイル用意していいなら bash --rcfile ファイル名 で .bashrc のかわりのファイルを指定するか。
(ファイルの先頭に . ${HOME}/.bashrc 書いておいて、追記分を2行目以降に記載)
すみませんが詳しい方のみ回答をお願いします
すみませんが2chに詳しい方のみ質問をお願いします
465 :
名無しさん@お腹いっぱい。:2014/03/09(日) 23:13:53.66
こういうのってぼっとなのかな?
手でやってるのかな?
超高性能ボットみのような人間がやってるんじゃね?
人工知能はいまだ自然言語の分解も怪しいってのに
質問と回答とその他が区別できる程の自然言語解釈とか無理だと思う
そうだな。的を外してる回答のみを抽出する処理も要るしな。
社なんとか室の仕事じゃね?w
PS1はプロンプトでしょ?
PS2ってなんだっけか
セカンダリプロンプト
自動的にプログラム実行時の実時間を環境変数に入れるように
プロンプトを改造したいんだけど、うまくいきません。
bashで、プログラム実行直前の時刻を取得する方法ってあります?
bashで無理ならzshとかいうやつでもいいです。
472 :
名無しさん@お腹いっぱい。:2014/03/10(月) 13:48:41.84
だからセカンダリプロンプトってなんだっけかって聞いてるんだろ。アスペかよw
man読めよ。
すみませんが詳しい方のみ回答をお願いします
history-all | tail
あたり
ないよ
historyじゃだめなの?
HISTTIMEFORMAT環境変数セットして
プロンプトに時刻入らなきゃヤダ。
プロンプト表示時点の時刻じゃなくて、
コマンド実行時にそのコマンドをタイプした前の行のプロンプトに時刻を入れる
というところがポイントな。
現在コマンド入力中のプロンプトは時計のように時刻を1秒毎にカウントアップしていて、
コマンドをタイプしたらその行プロンプトのの時計が止まってコマンド起動時刻を示す、
というのがいいな。
historyに時刻入れた方が便利そう。
>>479 HISTTIMEFORMATセットすると、
HISTCONTROL=ignoreboth が無効になる
当たり前なんだろうけどちょっとショック受けた
実行直前の時刻って何なの?開始時刻とは違うの?
呼ばれたコマンドが始まってしまったら
シェル側はどうこうできない。
呼ばれるコマンドが実行される直前に
シェル側で時刻を出す必要がある。
>>484 違わない
実行直前の時刻とは、開始時刻のことである
必要ならば図解しようか?
パスワード認証のsshでログインを自動化したいのですが、どのようにすればよいでしょうか?
expectコマンドはインストールしない方法を考えています。
echo -e "password\n" | ssh -t -t
[email protected] 上のスクリプトだとプロンプトが出てダメでした。よろしくお願いいたします。
>>489 失礼な話だが、釣り/荒し臭い質問だな。
適当に回答させて、いつものお決まりの文を書き込むのかな?
expectが何を出来るかしか知らないんだろうな。
expectが何をやってるか知っていればそんなマヌケな質問は出てこない。
回答:
expect入れたくなきゃexpectと同じ働きのプログラムを作る
>>489 何故パスフレーズなし秘密鍵ではだめなの?
>>492 Dockerのコンテナにsshでログインしようとしているのですが、秘密鍵を指定しても読み込んでくれずパスワード入力になりました。
それで秘密鍵なしで頑張ろうと試行錯誤している次第です。
>>492 ぼくのかんがえたさいきょうのパスワードくらっかーで、にっくきあいつのホストにろぐいんしてやるんだー。
ってことだろ
>>493 公開鍵方式で認証できるように試行錯誤しろよ。
>>493 $HOME/.ssh/authorized_keysないし、その祖先ディレクトリの
どこかが、グループかotherに対して書き込みを許してるってのが
チョーありがち。
てゆーか、まずログを確認すべきだね。
CentOSなら/var/log/secureとか。
>>496 $HOME/.sshフォルダがまるごと消えていたのが原因だったようです。。
きちんと確認しないといけないですね。ありがとうございました。
何それww
このスレには社史編纂室レベルの質問しかこないのか
噴いた
>>499 答えてるのも社史編纂室のおじちゃん達というオチか
社史編纂室厨いい加減うざい
糞質問する奴ともども氏ねや
bashで、プログラム実行後のカレントを保存する方法ってあります?
bashで無理ならzshとかいうやつでもいいです。
老けたせいでギャグの質が低下してるのを気がつかないのだろう
社史編纂質
すみませんが詳しい方だけ答えてうんたら
これらギャグのつもりなんだろうが
面白くないし、寒いし、うざい
「ギャグは繰り返し」を勘違いしてる、寒くてうざいもんは寒くてうざい
老化してるから
「ウざがられるためにやってるんですう」とか
小学生みたいにいってくるからヤメロ
カレントディレクトリか?
DIR=`pwd` とかそういう話かな。
DIR=$PWD でいいか。
>>504 > これらギャグのつもりなんだろうが
ギャグじゃなくて回答する人を弄ぶのが目的の荒しだと思うが。
> 社史編纂質
> すみませんが詳しい方だけ答えてうんたら
俺的には
「人を馬鹿にする事ばかりの虚栄心君」
もかな。
弄ぶついでにギャグか照れ隠しではさむ言葉のセンスについてだろうが
目的とか考えてもしょうがないよ。
それを理解できたら正気ではいられなくなる。
小バカにしようとする態度は見て取れるが
書きかたが悪いせいで、そいつ自身バカに見える
こんな感じの騒ぎを起こすのが目的だろ
この手のは完全スルーが一番
おっ、糞回答を自作自演してきたなw
すみませんが詳しい方のみ回答をお願いします
>>512 昔から言うよね バカのひとつ覚えってw
シェル初心者です。
シェル実行ファイル内に、
TEMP=`コマンド結果`
の変数があって、外部ファイル(SQL文)内に同じ変数
${TEMP}
を記述して、外部ファイルを読み込ませてSQLを実行させたいのですが、
変数に値が入るような書き方が分かりませぬ。
sed通すとか?
外部ファイルじゃなくてヒアドキュメントにするのがお手軽
予告しておこう
お前はSQLインジェクションを喰って死ぬほど後悔する。
>>519 やはり置換が必要なんですかね。
>>521 ヒアドキュメントで動作することは確認できたのですが、
外部ファイルに持たせる処理をスマートにやってみたかっただけです。
セキュリティ的にまずいんですかね このやり方。
>>522 回答でサニタイズが言及されていない時点で、(やり方もだが)
あなたの知識がセキュリティ的にまずいと思うわ。
SQLインジェクションは思いつきにくい方法でデータぶっこぬかれたり不正操作されるって
パターンなんで、どういう攻撃方法があるかを人とおり勉強することをオヌヌメする。
SQLはプリペアードステートメント使用が鉄則なのでシェルスクリプトで
処理しようというのが間違い
出た!サニタイズ!
サニタイズ言うなキャンペーンはひろみちゅの(シロートが書いたセキュリティ
対策本への)言いがかりなので、適切な文脈で使うのは全く問題ない。
適切な文章ではエスケープって単語が出てくるべきだしそれで十分だから、
サニタイズという単語が適切なケースなんてまず無いってのが根本にある。
劣化したエスケープにすぎないサニタイズで満足する考え方自体問題だし、
サニタイズなんて言葉使う考え方してるとそのうちエスケープ漏れで死ぬよ。
エスケープとサニタイズの関係はバグとセキュリティホールの関係に置き換えられる。
セキュリティホールとして悪用可能なバグじゃなくてもバグを肯定するのは駄目だろう。
正当な文字だけで構成されていなかったら、そこでエラー終了するという方法
だってかまわない。
その場合もエスケープか? 確かにエスケープだが意味が全然違う。w
ところで、パブリックアクセス可能なdbを作成する際にセンシティブな情報や
個人情報を取り除く事もサニタイズと言うのだが、これも「サニタイズ言うな
キャンペーン」に引っかかるのかね? どうやってエスケープするんだろう。w
話それまくってるな。
>>528 「センシティブな文字列」というものをそもそも作り出さないのが
サニタイズ言うな運動の肝なんよ
まあシェルスクリプトだとなかなか難しい話なんだけど、
Cとかでたとえるなら
system使うとコマンドラインインジェクションの危険あるけど
forkしてexecなら原理的にインジェクションは無いでしょ?
そういう積み重ねのことね。
セキュリティ言ってる人も
DBユーザの権限で制限するのあんまやんないよなぁ。
行ごとの権限ができないのはともかく。
>>530 >>528の後半部分の「センシティブな文字列」とはクレジット番号だったり
するわけだが
> 「センシティブな文字列」というものをそもそも作り出さないのが
> サニタイズ言うな運動の肝なんよ
クレジット番号を作り出さないとか、全く意味不明
>>532 入力された文字をサニタイズしてのではなく、入力されたデータ全部を
サニタイズしたと言っていい
自分の人生をサニタイズしてみたらどうだ?
自分じゃできないから誰か俺の人生をサニタイズしてくれ
>>533 入力されたクレジット番号を文字列に埋め込むときに
無検査で埋め込むなってことでしょ
そのつっこみの方が意味不明
>>536 >>528の後半部分は、
>>527 > 適切な文章ではエスケープって単語が出てくるべきだしそれで十分だから、
への反例として、
公開サーバに置くデータベースを作るときにセンシティブな情報や個人情報を
取り除く作業を行う。この作業の事をサニタイズという。
を例示した。この作業をエスケープとは言わない。
サニタイズはサニタイズ。エスケープでは置き換え不可能。
サニタイズ(Sanitize):消毒、除菌、無害化
個人情報って毒だったのかぁ〜・・・
そういえば2chでも住所書くとドメイン焼かれてたからねぇ〜・・・
「単なるNGワードだろ」って指摘も聞かなかったことにしてるようだし、
そもそも
>>518→
>>521→
>>523の文脈では個人情報の除去は関係ない
エスケープ言うべき所でサニタイズ言っちゃった典型的なサニタイズ脳
必死にサニタイズを擁護してるとこ悪いが、見てて哀れだからいい加減黙ろうか
>>538 >サニタイズ(Sanitize):消毒、除菌、無害化
>個人情報って毒だったのかぁ〜・・・
知らないで使ってたのかよ
>「単なるNGワードだろ」って指摘も聞かなかったことにしてるようだし、
2ch用語じゃ無くて正式な名称で言えば相手してあげるよ
>そもそも
>>518→
>>521→
>>523の文脈では個人情報の除去は関係ない
だから、「ところで」と話題変えてるだろ。
>>527は発言の有効範囲を限定してないからな。
あと、
>>518質問者
>>521オレ
>>523何処かの誰か
>>525キャンペーンをうのみにしてるアホ
>>526オレ
だからな、勘違いするなよ
>エスケープ言うべき所でサニタイズ言っちゃった典型的なサニタイズ脳
>必死にサニタイズを擁護してるとこ悪いが、見てて哀れだからいい加減黙ろうか
お前、やっぱりひろみちゅのキャンペーンの意図理解してないだろ。w
バカには覚えやすい標語与えといて、簡単かつ確実な方法を選択させるのが目的
エスケープする方法が与えられているバカ向けの環境でのみ成立する
コイツにとってほぼ全ての実用なプログラミング言語はバカ向けの環境なのか・・・・・・
皮肉すら分らんようだし突き抜けすぎててもう感動〜!
541 :
名無しさん@お腹いっぱい。:2014/03/17(月) 04:13:20.39
こいつパー速にいる気がする
http://takagi-hiromitsu.jp/diary/20060115.html > つまり、「サニタイズ」という用語が、各人の都合でどんな意味にも解釈され
> るという、「汚れた言葉」になっており、専門用語として使い物にならなくなっ
> ているのだ。もはや、「サニタイズする」は「セキュリティ対策する」と同義
> でしかない。そういう言葉には存在価値がない。加えて、特定の意味を指して
> 使っても別の意味で解釈されてしまうのだから、有害である。
ひろみちゅの思い込みと、思考能力がなくうのみにするバカの間でだけ通用する
言葉狩りキャンペーンって事だ
教祖様はNGワード(笑)にも言及してるな ブラックリストの事を言いたかったんだろ
> ブラックリスト方式ではなくホワイトリスト方式にせよという話だと誤読した事例
> 「/^[a-z]+$/のような正規表現」を使う手法はサニタイズ処理そのものであって、まさにセキュリティ対策のための処理である
続きは社史編纂室スレでやれよw
過去にひろみちゅに実名でコテンパンにやられた奴が、
逆恨みして暴れてるスレがあると聞いて飛んできますた!
何も考えずにひろみちゅの尻馬に乗ちゃったバカが憐れすぎる
>>533 サニタイズって言葉を再定義して使ってるのね。なるほど。
>>546 教祖様にいってやれよ。
つーか、お前のようなバカをサニタイズするために始まったキャンペーンだろw
http://takagi-hiromitsu.jp/diary/20060115.html >> たとえば、データファイルのファイル名の一部をCGIのパラメータと して受け取るようになっているPerlスクリプトなら/^[a-z]+$/のような正規表
>> 現(Rubyなら\A[a-z]+\z/)で期待している文字しか入っていないこと を確認して(Perlの場合はuntaintもこれで出来る)、違っていたらエラーにする
>> というのが「 セキュリティ対策以前に元来本質的に必要な処理」だと思います。
> ブラックリスト方式ではなくホワイトリスト方式にせよという話だと誤読した事例
> 「/^[a-z]+$/のような正規表現」を使う手法はサニタイズ処理そのものであって、まさにセキュリティ対策のための処理である
いえ、社史編纂室長です
社史編纂代行株式会社でも作るか
なんかサニタイズとエスケープの理解度があやしくないか?
大ざっぱにいえば、
サニタイズは、不要な文字を削ること。
エスケープは、特殊な意味を打ち消すことだよ。
用途、目的がぜんぜんちがうべ。
サニタイズされた文字列に特殊な文字が含まれる事はないし、逆にエスケープされた文字列から特殊文字が消えることもない。
エスケープの事をサニタイズと呼んだり
エスケープすべきところでサニタイズしたりする
>>523みたいなサニタイズ脳がわらわら居るからな
SQLインジェクションなんてエスケープ漏れの代表例出して
サニタイズすべきとか言う馬鹿を勘違いさせないためにも
サニタイズなんて単語は捨てた方が良い
シェルスクリプトでSQLをエスケープしてからほざけ
有害なものを無害化するエスケープがサニタイジングでしょ
エスケープの一種ってことで
まだやってる…
バリデーション「ぼくも入れて〜」
> 有害なものを無害化するエスケープがサニタイジングでしょ
> エスケープの一種ってことで
そういう定義にするのか? キャンペーンの信者 www
「エスケープ言うなキャンペーン」始めるべきですよ。ひろみちゅ先生
戻せないものはエスケープとは言わない。
ん?戻せないってなんのこと?
戻せなきゃSQLを実行できないだろ キャンペーン信者頭悪っ www
とっとと、SQLをシェルスクリプトでエスケープしろよ。
浸透「遊びに来たよ!」
>>558 サニタイズの用例には3つある
1、エスケープをサニタイズと呼ぶ
2、エスケープするべき文字(列)を単純に除去することをサニタイズと呼ぶ
3、NGワード同様、通過させては駄目なデータを除去・置換することをサニタイズと呼ぶ
複数の用例を区別せず「サニタイズは正しい」などと言ってると、
1の人はエスケープという概念を知りそこねて間違ったエスケープを行いエスケープ漏れを起こしやすくなるし
2の人は無意味にシステムへの入力制限やデータの損傷を起こした挙句エスケープ漏れを起こしやすくなる
そもそもエスケープをサニタイズなどと呼ぶべきではないし、3の用例もNGワードやフィルタリングと呼べばいい
この半ばスレチな話の発端である
>>523はSQLインジェクションを例に出してる事から3の用例では無いんだが、
サニタイズを擁護してる人は何故かその事実やサニタイズに複数の(誤)用例があるって事実を無視したり、
あるいは複数の用例を都合よく入れ替えて話を捻じ曲げて理論展開してたりと、無茶苦茶やってんだよね
誤用した自分の擁護で捻じ曲げてんのか、高木への恨みで捻じ曲げてんのか、自覚なく捻じ曲げてるのか…
>>523を擁護してるのではなくて、それに釣られて現れた盲信者をバカにしているわけだが。
>>563 とりま、釣られてみる。
何度も指摘されているけれど、エスケープをサニタイズとは言わない。
全く別のものなのに同じものと理解してるのがまずい。
正規化の一種として同じとかならまだわかるけど。。。
>>564 盲信云々以前に523が明らかにキャンペーン対象の典型例なんだが
>>565 563はエスケープをサニタイズと言う奴が居るとは書いているけれど
エスケープをサニタイズと言わない奴が居ることを否定はしてないぞ?
だからもうFランPG・文系SEがドヤ顔でカタカナ言葉使ってたら
まず間違いなく意味わかってないってことでいいだろ
正直スレチ
エスケープが正しいと言ってた人
シェルスクリプトでSQLをエスケープする実例見せてよ
あっと、pgbashとか飛び道具なしね
悪意あるデータが混入するリスクのある状況で、
プリペアードステートメントのない言語選択するのって、
シェルスクリプトしか使えない老害ぐらいじゃねえ?
悪意あるデータは数字しか来ないと分かってる
例外的状況ぐらいしか、使う言い訳できるケースを思いつかん。
結局ひろみちゅのキャンペーンはサニタイズ脳を撲滅しようとして
エスケープ脳を量産する結果に終わってしまいましたとさ。
エスケープ脳の見分け方
「サニタイズ」と唱えると楽勝で判定できる
プリペアードステートメント万能かというとそうでもない
ひろみちゅも当初は誤解してたふしもあったけど
実装によっては(例: 古めのpostgreSQL)SQLへの展開をクライアント側でやっ
てて、結局phpとかに標準で入ってるエスケープ関数と同等ってのもある
おまえさんこそ、反省した方がいいよ。
それは、「プリペアードステートメントではないものを、プリペアード
ステートメントだと誤解していた」っていう例だぜ。
そいつを「プリペアードステートメント万能かというとそうでもない」と
表現しちゃうってことは、おまえさんが、プリペアードステートメントを
理解してないか、致命的に日本語が不自由か、どちらかだっていうことだ。
社史編纂室は社史編纂してたらそんでええの
お前の論理で言うとlibpqが
> PQprepare
> Submits a request to create a prepared statement with the given parameters,
> and waits for completion.
と「プリペアードステートメントではないものを、プリペアードステートメント
だと詐称していた」わけだが。
何かほかに質問はあるか? 無職
2chスレ全体でやってる対立煽り工作がシェルスクリプトスレまでやってきた
て、ことだろう
このスレに対立楽しみたいという血気盛んな若者が居るとも思えんのだが
そうなんだろう
>>575 さすが老害は時代感覚が狂ってるな。
PostgreSQL にホンモノのプリペアードステートメントがなかったのって、
PostgreSQL 7 の時代だぜ。
10年くらい前にはもうホンモノのプリペアードステートメントが入ってる。
Wikipedia
ttp://en.wikipedia.org/wiki/Prepared_statement で確認しても、
ホンモノのプリペアードステートメントは server side で動くものって
書き方になってて、client side でやってる奴は emulation 扱いになってるぜ。
つまりホンモノのプリペアードステートメントじゃないってことだよ。
10年前ならともかく、いまさら PostgreSQL の過去の誤用を元に主張されても。
クライアントサイドでの実装がありうるという実例だよ。
お前、全部の実装が「ホンモノのプリペアードステートメント」であることを
確認してるのか? 大変だな。 w
セキュリティ気にしてる人間なら、当然チェックするだろう。
実際、クライアント側でエミュレートしているおかげで、
セキュリティホールがあったって事例はいくつもあるわけで。
そういう当たり前の作業もやらずに、セキュリティを語ってるわけ?
呆れた。
そりゃシェルスクリプトでサニタイズに問題感じないわけだ。
ぷぷぷっ 矛盾してるぜ。「10年前ならともかく」な事を「当然チェック」するのか? ww
>>577 > 10年前ならともかく、いまさら PostgreSQL の過去の誤用を元に主張されても。
>>579 > セキュリティ気にしてる人間なら、当然チェックするだろう。
いまでも、DB実装とライブラリの組合せによっては、
クライアント側でエミュレートするケースってのがありうるんだよ。
PHPのPDOとか、DB側でプリペアードステートメント用意してる場合には
当然使うが、用意してない場合には、クライアント側でエミュレーション
する機能がある。当然、こういうライブラリ使う場合には、そのDBで、
ちゃんとプリペアードステートメントになるか確認する必要がある。
こんなことも知らずに矛盾だと思っちゃうとか、よくセキュリティを
語る気になれるなあ。こういう奴の言ってることを間違って信じちゃう
奴がいると危険だから、ホント黙って欲しい。
どっちも荒らしだから黙れ
いや独演でひとりか?
こっちはどう言い訳するんだ?
>>577 > 10年前ならともかく、いまさら PostgreSQL の過去の誤用を元に主張されても。
どこに説明の必要があるの?
・10年くらい前の PostgreSQL は誤用していた。
・今でもプリペアードステートメントを、「エミュレート」するケースは存在する。
(エミュレートなので、実際にはプリペアードステートメントにはなってない)
ってだけでしょ。
>>584 プリペアードステートメントではないものを、プリペアードステートメントだと詐称している実装が存在する事を知っているなら
>>573のような間抜けな発言はしない。
>>573 > おまえさんこそ、反省した方がいいよ。
> それは、「プリペアードステートメントではないものを、プリペアード
> ステートメントだと誤解していた」っていう例だぜ。
誤解していたのは、当時のひろみちゅだろ。
何が言いたいのかさっぱり分からんわ。
それはお前の日本語能力が決定的にダメなのだろう。
> ひろみちゅも当初は誤解してたふしもあったけど
最初から言ってるが。
むしろ、あんたの現実認識能力に問題がある気がするが。
当時ひろみちゅが誤解してたって話と、
>>584 にどういう矛盾があるんだ?
最初から当時ひろみちゅが誤解してたっていってるのに
>>573と言いがかりをつけるのは、お前の日本語能力が欠如しているせいだろう。
これひとりで延々書き込んでるの?
何言ってるの。
>>575 で、「PostgerSQLがプリペアードステートメントだと
主張してるから、client side でやっててもプリペアードステートメントだ」
って意味の主張してるじゃん。
自分の主張ももう忘れたの?
当時のPostgerSQLは間違えてんだよ。
そのことを分かってないのは、
>>575 を書いた奴だ。
>>590 スレ違いすまん。少なくとも2人はいるんだ。
設定が2人以上とな
コマンドインジェクションをおこさないようにeval使いたいんだけど
どうしたらいいかな
evalをサ二タイズ
>>569 シェルスクリプトでエスケープできると言ってる奴は居ない
むしろサニタイズすべきといった奴がサニタイズ例出すべきだな
>>591 徹底的に日本語能力が欠如しているな。
「お前の論理で言うと」と前置きしてるだろ。
エバラ
焼肉の
ここで議論することじゃないだろ、お互いメルアドでも交換して続きはそっちでやってくれ
俺は目玉焼きはサニタイズよりターンオーバー派
議論の経過を第三者に見てもらいたいからメールじゃ駄目なんだよ
>>602 じゃあ、IDの出る板で、ここじゃないどこかで、
納得のいくまで議論をしてきてください。
議論の経過をシェルスクリプトスレの住人に見てもらいたいんだよ
議論の経過をサ二夕イズ
何この社史捏造室
編纂作業の傍らサニタイズについてブツブツと一人議論する元シス管か
$ mgrep [<options>] -e <pattern> <file>
でmigemoしたpatternで検索できる以下のようなmgrep関数を作った。
しかしこのままだと、patternの前に必ず -e オプションを付けんにゃならん。
$ mgrep [<options>] <pattern> <file>
でも同じようにmigemoしたpatternで検索したいんだけどどうしたら良い?
パイプした時も使いたいから <file> は存在しない可能性もある。
function mgrep() {
local -a args
local prev
for arg in "$@"; do
if [ "$prev" = '-e' ]; then
args+=$(cmigemo -d /usr/local/share/migemo/utf-8/migemo-dict -w "$arg")
else
args+="$arg"
fi
prev="$arg"
done
grep -E "${args[@]}"
}
パターンはスラッシュでくくる、とかの仕様にすればいいんじゃ
expr match "$arg" '/\(.*\)/'
にマッチすればパターンとみなすとか
if [ -n "${file:-}" ]; then
↑こういう書き方をしてるスクリプトがあるんですが、これって
if [ -n "${file}" ]; then
↑
と単に書くのと何が違うんでしょうか?
おしゃれ
>>612 set -u してる場合にエラーを回避することができる
>>613 すみませんが詳しい方のみ回答をお願いします
>>615 ${parameter:-word} 自体の意味を質問してるんじゃないよw
だから
>>614 の回答が適切。
>>612 $ set -u
$ unset file
$ echo "${file}"
file: unbound variable
$ echo "${file:-}"
(エラーなし)
set -u してなければ "${file:-}" も "$file" も同じ。
>>615 は問題ちゃんと読まずに解答するタイプw
>>616 ${parameter:-word} 自体の意味がわかってたら
なぜそう書くのかもわかるんじゃね?
>>618 ${parameter:-word} 自体の意味はわかってても、
その word の部分を空文字列にする場合の意味がわからないってことだろ
wordが空文字列なら ${parameter} と同じでは? という質問だろ
>>619 > wordが空文字列なら ${parameter} と同じでは? という質問だろ
そういう疑問が出るってことは
${parameter:-word} 自体の意味をわかってないでしょ。
>>620 ${parameter:-word} 自体の意味をわかってるからこその疑問だろ。
man見ても set -u のことはそこには書いてないからますます疑問になるはず。
>>614 ありがとうございました。変数未設定の場合の /bin/sh -u の対応ですね。
>>615 さん、それは知ってますよ。
-uの方の説明も、${parameter:-}の方までエラーになっても不思議ではない記述のような・・・
つまりシェル変数をサニタイズするわけですね!
>>set -u してる場合にエラーを回避することができる
だけど、set -u してる場合はエラーを回避しちゃ
駄目なんじゃないだろうか
>>625 おまえ、ホントに理解してない奴だな。
set -u はプログラムミスで変数名が違ってたりするのを防ぐのが狙い。
if [ -n "${file:-}" ]; then
なんかの場合は $file がセットされてないかどうか自体を条件判断してるんだから、
if文を実行して file: unbound variable なんてエラーメッセージ出されたら困るだろ。
ん? set -u って防ぐのが目的ではなくて検出する(そして人間が修正する)
のが目的なんじゃないの?
>>627 「検出する(そして人間が修正する)」のことを簡潔に「防ぐ」って言ってるんだろw アスぺかよw
>>626 お前ホントに何もわかってないのな
プログラムミスを検知するために-uしてるのに
プログラムミスを検知しないようにしてどうする
ってことだ
>>629 if [ -n "${file:-}" ]; then
の場合はそもそも set -u ではミス検出できない。
$file の状態がどちらであっても正常だから。
お前ホントに何もわかってないのな
>>630 「set -u を使う事を前提とするなら」、 if [ -n "${file}" ]; then と書くべきなんじゃないか?って話
>>632 正反対。
「set -u を使う事を前提とするなら」、 if [ -n "${file:-}" ]; then と書くべき
set -u には、${file} 以外の箇所を検出させる。 $hoge とかが他の場所にある。
>>631 言葉の表面上の意味でしか捉えられないアスペ乙
>>632 Makefileで、 (コマンド || true) とかやってエラーにならないようにするのと同じようなもの。
この行だけ set -u に検出されないように "${file:-}" って書くわけ。
C言語でwarning消すためにキャストするのとも似てる。
warning消しておかないと本当のwarningが出る他の行と紛らわしいから。
>>633 う〜ん、間違えて if [ -n "${flie:-}" ]; then って書いちゃったらどうするの?
>>635 それもよく判らないなぁ。$file が未定義なのかNULLなのか判別しないまま
スクリプトの実行を続けても構わない、ってこと?
>>638 ∧∧
ヽ(・ω・)/ ズコー
\(.\ ノ
、ハ,,、  ̄
 ̄
その例だと分かりづらいのかも
他の例を挙げると、引数を確認する目的で
echo "arg1=${1} arg2=${2}"
と書くのを、
set -u
echo "arg1=${1:-} arg2=${2:-}"
としないといけない、とか
>>630,633,635
それだったら
file=""
:
:
if [ -n "${file}" ]; then
って書いたほうがいいんじゃない? 変数名の書き間違ちがいもチェックできるし
${xxxx:?msg}の事も思い出してあげてください。
こんな機能があるのな
いままでif連打して引数判定してたのが馬鹿馬鹿しくなってきた
三項演算子とかでググってたのがいけなかったのか
>>632>>633 どっちも正解
「set -u を使う事を前提とするなら」「空文字列判定を意図する部分では」「if [ -n "${file}" ]; then と書くべき」
「set -u を使う事を前提とするなら」「未設定の判定も意図する部分では」「if [ -n "${file:-}" ]; then と書くべき」
>>636 アスペ(もとい自閉症スペクトラム)の症状は色々な方向性がありうるから一概に間違ってるとも言えない
>>645 とはいえ、
>>634 は単に「アスペ」って言いたいだけなんじゃないかと
色々な方向性がありうるとなると
>>634 がアスペなのかもしれないが…
なんだよ、もっとサニタイズしろよw
648 :
名無しさん@お腹いっぱい。:2014/03/29(土) 08:35:58.71
そんなに悔しかったのか? エスケープ脳 w
シェルスクリプトでSQLをエスケープして見せてくれよ。
へんぴなスレで無理やり対立煽られてもなあ
困っちゃう(社交辞令
>>645 それを踏まえて
>>625 を言っている。
どうも根本的にわかって奴が一人いるようだけど・・。
set -u は未設定(というミス)を検出するためにやっている。
その状況で、「この変数は未設定かもしれないけどエラーにならないようにしよう」とするぐらいなら
空文字列でも設定しておけ、ってこと。
>>650 空文字列設定するのにもう1行要る。ダサイ書き方になる。
空文字列設定すること自体が副作用になるから、それがNGの場合がある。
未設定変数は未設定のまま(空文字列も設定せずに)放置して、ifで条件判断だけしたい場合とか。
>>642 fileにすでに何か設定されてるかも知れない状態で呼び出されるスクリプトまたは関数だったら、
file='' とかやったら駄目じゃんw (ちなみに、file= だけでもOK クォート不要)
>>650 一行増えるのがダサイねぇ… 副作用が NG とか if で条件判断だけしたい
場合って具体的にはどんな場合なの?
>>652 その前提だったら未定義かどうか調べないでいきなり if [ -n "${file:-}" ];then って
しちゃったらまずいだろって話。ああ、
>>639 に戻ったw
>>655 その前提だからこそ未定義(空文字列含む)かどうか調べるために if [ -n "${file:-}" ];then って
してるんだろ。お前理解遅いなw
前提:未定義と空文字列は同じとみなす
(未定義or空文字列)なのか、文字列がセットされてるのか調べたい
変数に勝手に空文字列を代入してはいけない
調べる際に、set -u された環境でもエラーにされないようにしたい
それだけのこと。簡単だねw
>>656 ん?調べてないよ。未定義でも空文字でも false になる
>>658 それでいいんだけど、、何勘違いしてるの、君一人?
>>658 は
>>657 読め。
未定義でも空文字でも false にしたい。
文字列が長さ1以上あれば true にしたい。
未定義のとき、set -u を回避したい。
>>662 それじゃ set -u 使う意味ないんじゃない?
>>661 C言語でwarning回避するためにキャストしたとき、キャスト元の方が本当に間違っていても検出できないのと同じ。そこは問題にしない。
>>664 いや、C言語のワーニング回避とは関係ない
これ、誰が暴れてるの?
外した回答叩かれた
>>615 が一人で暴れてるのかな?
669 :
名無しさん@お腹いっぱい。:2014/03/29(土) 13:22:49.28
そろそろ、一種の集団ヒステリーを述べる言葉、
あるいはひとつの格言を挙げておきたい
「バカは感染する」
大元の
>>612 で言ってる「こういう書き方をしてるスクリプト」
の全体を見てみたいものだ
話は変わるけど、set -u を使わないで変数が未定義なのかどうかを
調べるってお題があって、
undef="false"
if [ "${var-UNDEF}" = "UNDEF" ];then
if [ "$var" = "" ];then
undef="true"
fi
fi
なんで空文字かどうかを調べてるんだろうって思ったら var="UNDEF" って
なってる場合に対応してたのね
>>673 変数が未定義という条件判断をするなら、
if [ -z "${var+DEF}" ]; then echo varは未定義; fi
だけで簡単に記述できるね。
>>672 set -u 回避が正解って前提で話が盛り上がってたけど
全然関係なかったりしてw
>>672 > 大元の
>>612 で言ってる「こういう書き方をしてるスクリプト」
> の全体を見てみたいものだ
例えば、
$ grep -iE '\$\{[a-z]+:' /usr/sbin/mkinitramfs
if [ -n "${UMASK:-}" ]; then
if [ -z "${compress:-}" ]; then
DESTDIR="$(mktemp -d ${TMPDIR:-/var/tmp}/mkinitramfs_XXXXXX)" || exit 1
__TMPCPIOGZ="$(mktemp ${TMPDIR:-/var/tmp}/mkinitramfs-OL_XXXXXX)" || exit 1
if [ -n "${ROOT:-}" ]; then
全体は長すぎるので省略します、あしからず
mkinitramfs、-o オプションを付けないと outfile 変数は
set -u で引っ掛かってしまうのにそのままなんだな…?
if [ -z "${outfile}" ]; then
usage
fi
報告したげて。
外部プログラムにスペースを含む引数を渡したい
この引数は他の引数と一緒にシェル変数に格納される
このシェル変数名は別の変数に変数名で格納されていて
実行時にevalして実行される
試行錯誤した結果二回evalという解決策にたどり着いたけど、何かスマートじゃない。
もっとスマートな方法はある? スペースを含まないなら一回のevalで済むんだが。
argspecをevalって実行するという部分はいじれないのでそれは無しの方向で
抜粋部分はこんな感じ
echo_it() { for a; do echo $a; done; }
argspec="\$opts $DEFAULTS"
opts=
opts="$opts arg1"
opts="$opts \"arg with space\""
eval set $argspec
eval echo_it "$@"
俺なら、どこか前処理でスペースを別の使わない文字か
あるいは使われない単語に変換して、呼ばれた側で同様に変換して戻す
という方式にする
無理にスペースをエスケープするより、綺麗になることが多い
>>681 と被るけど、IFS を TAB だけにしちゃうとか
(ただし、引数にTABを含む文字列が使えなくなるけど)
opts="$opts arg1"
opts="$opts arg with space"
argspec="$opts $DEFAULTS"
OLD_IFS=$IFS; IFS=$'\t'
set -- $argspec
echo_it "$@"
IFS=$OLD_IFS
スマートかどうかは…不明
テキストファイルについて、grepしたりsedしたり…といった整形処理をするシェルスクリプトを
作ってます
このファイルの末尾6行は不要なので、今は前処理で head -n -6 として削ってるのですが、
シェルスクリプト中でawkを使ってる部分が結構あるので、その処理をawkにて
置き換えられないだろうか、と考えてます
awk '/hoge/{
do {
〜処理〜
if (NR > 総行数 - 6) exit; ←
} while (getline)
}'
…みたいに「←」の様な記述を加えてやればよいのかなと思ってたのですが、しかし総行数は
ENDセクションにならないと分からないということでうまくいきませんでした
awkでうまく処理する方法、ありますでしょうか
事前にwcで行数を数えておき、それをawkに総行数の変数として渡して…というのは
うまくいったのですが、パイプが途切れるためかwcの仕様か、性能がかなり悪化してしまいました
perl使えるのなら@lines=<>;とすると、行単位に配列に入るのでspliceと組み合わせれて便利かも?
awkでやりたいんだよ!
6行分のバッファを持っといて1行読むごとに6行前の行を処理すればいいんだけど、awkでどう書くかは知らない
{
a[NR]=$0
if (NR>6){
$0=a[NR-6]
} else {
next
}
}
ってのをスクリプトの先頭につっこんでおけばいいかな。試してないけど。でも、
>このファイルの末尾6行は不要なので、今は前処理で head -n -6 として削ってるのですが、
これでいいと思う。
688 :
683:2014/04/24(木) 23:52:15.46
皆さん意見ありがとうございました
6行分のバッファを、と見て、ほほーと思って途中まで実装してみましたが、
なんというか、非常によく分からないスクリプトになってきたので、やめました…
現状どおり、headで削る、でいこうと思います
>>687 入力全部配列に突っ込むなら、普通に全部読み込んでから処理した方がいいんじゃね?
a[NR%7]とa[(NR-6)%7]にすれば良いんじゃね。
$ seq 1 10 | awk 'NR > 6 {print _[NR%6]} {_[NR%6] = $0}'
1
2
3
4
リングバッファーきたー
て言うか、定番でしょ。
>>691 printしてしまわずに、そのあとの目的のawk処理につなげるにはどう書くの?
awk 2つをパイプでつないだのでは無駄なので。
687を690にして使うか、691でprintの所に処理本体を_[NR%6]使って書き直す
>>691 $0に代入直して新規行入力のつもりで処理を続行すればいい。
awk '{if(NR>6){$0=_[NR%6]}else{_[NR%6]=$0;next}} {ここにやりたい処理}'
>>697 俺awk使えないから予想だけど、%0以外の自動更新される値が6行先になる?
GWにシェルを始めようと思ってます。
cshは古い、bshは当たり前? じゃあashか? ashより優れた sshにするか?
コンサートだとA席よりS席の方が上ですよね?
701 :
691:2014/04/25(金) 23:22:31.10
素直にhead使っとき。↓bash
$ paste <(seq 1 10) <(seq 11 20) | awk '{l = $0} NR>6 {$0 = _[NR%6]} {_[NR%6] = l} NR>6 { printf "%d + %d = %d\n", $1, $2, $1 + $2 }'
1 + 11 = 12
2 + 12 = 14
3 + 13 = 16
4 + 14 = 18
見れば見るほど、head併用が正解だな
UNIX哲学
http://ja.wikipedia.org/wiki/UNIX%E5%93%B2%E5%AD%A6 1. 小さいものは美しい。
2. 各プログラムが一つのことをうまくやるようにせよ。
3. できる限り原型(プロトタイプ)を作れ。
4. 効率よりも移植しやすさを選べ。
5. 単純なテキストファイルにデータを格納せよ。
6. ソフトウェアの効率をきみの優位さとして利用せよ。
7. 効率と移植性を高めるためにシェルスクリプトを利用せよ。
8. 束縛するインターフェースは作るな。
9. 全てのプログラムはフィルタとして振る舞うようにせよ。
コレに従ってればわりとハッピーなスクリプトが書けるって話だからスレにはあってると思うが。
板に至ってはUNIX板より適切な板はないだろってレベル
systemdはこれに反しまくってるな
特にjournaldなんか独自バイナリにログ入れて
journalctlでしか見れないようにしててめっちゃ不便
>>706 ほんとこれ
トラブったときのログも特定の環境でしか読めないとか氏んでほしい
シェルスクリプトはいい加減滅びろよと思うのは私だけ?
バッチ処理ならいいけど、条件分岐が入った時点でperlなりpythonなり使えと思うんだけど
>>709 perlやpythonが入ってない(入れられない)環境もあるってことなんじゃ。
組み込み、UNIX、Linuxでもシェルさえある環境ならOK、
ってのはなかなか強力な利点じゃないかね。
>>709 ashならバージョン互換性とか気にしなくて良いんじゃないの。
置き換えられてたらpython2.7とか一生アンインストールできなくなりそう。
個人的にはperlこそいい加減滅びよと思ってるけどな
system();だらけのスクリプトとか後で読みたくないし書きたくない。 空白入りの引数の処理も面倒そう。
シェルスクリプトなら3〜4行で終わるものが、何十行にもなってる python スクリプト見たこともあるわ。
適材適所なんだしどっちかに滅びろよとか言ってる時点でどうかと思うな
何でbashで条件分岐使っちゃ駄目なのか良く分からんし
バッチ処理って単語の使い方が何か違う気がするし
bashを使ったらそれはバッチ処理ではなくてバッシュ処理だからな
つ、つまらん…
シェルの基本的なコマンドを網羅したライブラリはほしいね。
そうすれば ` ` を使わなくて済む
perlのCPANなら数は多いし大抵のことはできるんじゃないの
でもいちいちライブラリ入れるの面倒だし
仕事でサーバとか使ってると「追加ソフト入れるの禁止」
って状況はそれなりにある
知らん間に開発・検証用マシンに入ってたCPANのライブラリに依存しており、
商用じゃそのPerlスクリプトが動かんかった、という凡ミスが連発した結果、
必要なライブラリを書面で説明できないPerlスクリプトは商用適用NG、となった
自分で書いてみればperlやpythonよりシェルスクリプトの方が便利だってわかるのにな
コマンドの実行とか
適材適所
ただし、perl の適所はなくなったので、早く滅びろ
perlに親でも殺されたか
じゃ、一行野郎は何使うんだよ。
シェルスクリプトでええやん…
シェルスクリプトの意味わかってないだろ
>>723 rubyでいいんじゃない。短くかけるし。括弧言語じゃないから定義とか書くのは辛いけど、処理だけが目的なら代替手段あるだろうし。
rubyがインストールされてるサーバは、少なくとも俺の身近には存在しない。
perlが駄目だと言うのなら、次に考えるのはawkかsedだろ。常識的に考えて。
好きなの使えばええがな。
>>726 ruby()
>>727 sedでは足りないのをperl使うのだ
awkは半端だからフィールド抽出以外には使わない
結論: 一行野郎に対する代替が無いのでperlは存命
rubyがインストールされてないサーバは、少なくとも俺の身近には存在しない。
rubyが駄目だと言うのなら、次に考えるのはawkかsedだろ。常識的に考えて。
ていうかperlを存命させるかどうかってのはそのOS、ディストリのコアな部分からそれを排除できるかの問題だろ。
rubyは入れる物を多少選べば排除できるが、perlへの依存を全て排除するのは無理ではないが結構面倒だろう。
ここ何のスレだっけ。
rubyとperlを罵倒しながら気分転換にシェルスクリプトの話をするスレ
自分で環境作れないとこで、長々とワンライナー書くこともあまりない気がするけどなぁ。運用の人は書くのかな。
ビルトインとsedとawkで大抵こと足りるからな。perl使うのに多いのはライブラリ使いたい時とか。
でもそうするとpythonやrubyの方が最近のものがある気がする。pmとかまだ作られてるの?
>>729 一行野郎と言えば「awkは書かねぇ、たった一行」だろ?
736 :
名無しさん@お腹いっぱい。:2014/05/21(水) 03:32:28.76
うちのdebianにはperlとpythonは入ってるがphpとかrubyは入ってない
Windowsですらtexと一緒にperl/awk/sed/grep辺りが住んでたりするな
入ってないっていうか入れてないんだろ。
>>730 rubyを入れなくても何にも困ってない rails?()
perlを入れてないとコンパイルできないものが結構ある(PostgreSQLとか)
ruby信者の視野狭窄は異常
rubyで書く奴のおかげでrubyからpythonへの書き換えで飯が食えるとかなんとかw
>>739 コンパイルの依存関係にperl入れるのは辞めてほしい
>>741 autotoolsに依存するより全然まし
やっぱxmkmfだよなw
>>739>>741 コンパイルの依存関係にrubyやpythonが入るより少しはマシ
って言おうかと思ったけど自分の遭遇トラブルはperl依存モノの方が多かったorz
>>742 コンパイル省力化に高機能なツールや言語を使い出して、
今度はそっちの互換性問題が火を噴くとか本末転倒にもホドがある…
最小限のシェルスクリプトかMakefileで済む奴が一番気楽だわ
> って言おうかと思ったけど自分の遭遇トラブルはperl依存モノの方が多かったorz
その分野ではrubyやpythonは使われてないからだろ。特にrubyは日本限定末端土方専用だから。
使われてなきゃトラブルには遭遇しない。当たり前だ。
FreeBSDのperl依存地獄は凄いからな
perlのアップデートとかなったら阿鼻叫喚の渦
あと何かのプロジェクトで頑張ってperl依存をなくしたってニュースになったな
perlは撲滅すべき悪ではあるがまだ依存関係から取り除けてない害虫みたいなもんなんだろう
>>743 お、懐かしいね。Canna じゃまだ使われているのかな?
そういや Perl で one liner って使わなくなったな…
昔はこんなのを↓よくやってたけどね
$ perl -pi.bak -e 's:#!/usr/bin/perl:#!/usr/local/bin/perl:' *.pl
最近使ったのは…Run Length Encoding かな
$ echo '......' | perl -pe 's/(.)(\1+)/$1.(length($2)+1)/ge'
RLEって sed や awk, UNIX tools を組み合わせて one liner でできるのかな…
>>746 お察しの通りFreeBSDだが、FreeBSDは脱GPL脱GCCの実績が有るし今後に期待?
RELENG_5あたりでbaseからは脱Perlしてるじゃねえの
確かに今では base に perl が含まれてはいませんが、実際に perl を入れずに
運用しているサーバを私は見たことがありません。
でも perl が入ってないサーバって、実は世の中には結構あるんですかね?
perlなんて当然入れてない
元からperlなんて入っていないし、要らない。
必要なら入れれば?な感じ。
Debian wheezyの標準的なapt-lineで、各言語に依存するものの数を数えた。
その言語自身のセクションと、libsは除いてみた。
$ for l in perl python ruby ;do echo -n "$l ";aptitude search ~D$l\!~s$l\!~slibs|wc -l;done
perl 962
python 1603
ruby 204
今日からperlやめてnode.jsに移行してみる
>>758 それでタイプ量の多さに失望するんですね。
シェルでテキスト処理の部分だけperlでやるのが一番無難だと思うけどなぁ。
sh系なら-e''の中に改行含めれるし。
最近はもう、awkをさけるようになったなぁ
なんで正規表現の互換性をなくしてしまったのか。
>>742 autotoolsって、シェルスクリプトとm4とmakeで
できてるから、このスレ的には新参スクリプト言語よりは
歓迎なんじゃないかって気がするw
「〜に依存する」だけならそれ入れれば済む話だが、
「auto」toolsはマニュアルで修正しないとコンパイル通らない場合が…
修正マニュアルがあるならいいじゃないかw
764 :
名無しさん@お腹いっぱい。:2014/05/25(日) 14:19:48.29
マニュアル=手作業 とマジレス
FreeBSDが脱cshできればperlもしぼんでくと思う。だからまずしぼまない。
いや、src.confでコンパイルしないようにするだけ。
もう、何年も前からcshは入ってないが何も不都合は生じてない
数百万行のテキストをshのツールに食わせて実行結果を得る、なんてことをよくやるんだが、
プログレスバーを作って待ち時間のストレスを抑えようと思う
今何%進んでるかは実行行/全体行で簡単に分かるんだが、これを画面上に出力する時に、
単純に計算結果を出力するだけだと
[05%]・・・・・
[06%]・・・・・・
[07%]・・・・・・・
という風に毎回改行されて表示されて画面が汚くなるのが嫌だ
つまり何が聞きたいかというと、既に出力された結果を書き換えるような仕組みはshで実現可能なのだろうか
分かりにくくてすまない
^M のあと tput el しとくといいかも
tputってFreeBSDで互換性ないんだよなぁ、、
echo のオプションとか printf とかは?
>>768-769 ありがとう。tputを初めて知ったが、勉強してみる
しかし^Mがわからん。何のことだ
>>771 echo -nで改行無し出力は出来るから、いわゆる伸びていく棒は再現出来た
が、すでに出力したn%のnを書き換えるような操作が出来ない
printfはそういうの出来るんだろうか?
>>772 コントロール-Mを知らんのか? キャリッジリターンだぞ。カーソルは左端に戻る。
マジかよ
いや^MがCtrl-Mなのは知ってたけどそんな効果あったのか
次会社いったら試してみる、ありがとう
ついでに調べてたら、某ブログでecho "\r\c"なるものを目撃した
これも同じ意味かな
>>774 もしNetBSDならprogress(1)に逃げるって手もある
echoはポータビリティに難があるのでprintfの方が良い
printfもポータビリティに難があるが、、
dialog --gauge もある
>>770 FreeBSDがどうのというより、termcapとterminfoの違い。
>>779 そんなことわかった上で言ってるんだがw
??rで行頭からかくか、エスケープシーケンスでいいんじないかな。
ただ、ログのこと考えると、ただ延びていくだけのプログレスで十分だと思うけどなー
URL1=...
URL2=...
URL3=...
と定義して
for ((i=1;3>i;i++))
do
処理
done
の形で $URL$i と書いても URL1 などに展開されないのだが
正しくはどう書けばよいのでしょうか?
eval echo '$'URL$i
eval url='$'URL$i
echo $url
配列にしちゃうとか。
declare -a URL
URL[1]=...
URL[2]=...
URL[3]=...
for ((i=1;4>i;i++))
do
echo ${URL[$i]}
done
>>767 数値とプログレスバーと両方あるといいね。rpm -ivh みたいに。
sun wsのブート時みたいに棒を回すのもなかなかいいよ
i<3 にしよう
シンタックスエラーでなかなか回答遅れて申し訳なかったです
とりあえず暫定的に下のforループでしのぎました。
数が多くなると保守性が終わるけど。
for i in $URL1 $URL2 $URL3
do
......
done
>>783,784,786
文字連結のための''を使った回避術、
declareを使った配列宣言、
いいアイデアをいただきました。ありがとうございます。
棒回しいいなー
上書き方法会得したらそれも試してみよう
while :; do
for t in '|\r' '/\r' '-\r' '\\\r'; do
echo -en "$t"
sleep 0.1
done
done
何かと思ったら棒回しか
\\がうまくいきゃいいが
791 :
787:2014/06/08(日) 17:36:41.96
>>784 配列良いね
素晴らしく短くまとまった
保守性もばっちりだ
重ね重ね感謝申し上げる
URL=( \
#valiant
http://m... #watchSomething
http://j... #script
http://b... )
# download from URL, and add header
for ((i=0;i<3;i++))
do
echo ${URL[i]}
done
3から不変ならいいんだが、配列にするならこうしてみるのはどうか
for ((i=0; i<${#URL[*]}; i++))
do
echo ${URL[i]}
done
手元に実行環境がなくて検証出来ないから間違ってたらスマン
>>792 ありがとう。
httpで件数だけ埋め込む作業要らなくなった
${#配列名[*]}で取り出せるのか
こんな#が合ったなんて知らなかったよ
テンポラリファイルの扱いについて訊きたい
一部のファイルをrmしてないバグがあるスクリプトを走らせてしまい/tmpに多数ファイルを残してしまった
このようなミスを抑える対策とかありますか
>>794 入力、処理、出力、という流れを意識して、設計書を書き、
ポイントポイントで処理の目的に即したテスト項目を作って、
結果を他人が評価できるようにテストを実施することだよ
>>794 シェルスクリプト一般だと、tmpfile(3)みたいにプログラムが終わると勝手に消える
ようにするのは難しいだろうね。頑張れば出来るかもしれないけど・・。
一時ファイルというと、とりあえずファイル名に$$を入れたりすることが多いけど、
そういうのを含めない(可能なら固定名にする)のが、バグがあっても
悲惨なこと(/tmpが枯渇するなど)にならない設計方法のひとつ。
もちろん可能な場合だけど
>>794 オブジェクト指向で設計し、インスタンスの寿命が尽きる時にファイルが消去されてることを確認し、されていなければ破棄する。
サポートされていない言語だと例外時に忘れがちなので注意。
開始時に mkdir /tmp/アプリ名-プロセス番号/ してそこに作業ファイルを置いて、終了時に
rm -f /tmp/アプリ名-プロセス番号 すれば良いだけでは?
trap 使えば SIGTERM とか SIGINT にも対応できるし、bash なら終了時にキックもできる。
複数インスタンスの稼働を想定しないなら
>>796 の言うように名前固定して、既存ファイルが
ある場合にエラーでとまるようにするとかもアリかな。
小手先の対応で何とかするよりも、ちゃんとテストする方がよかろうよ
>>795-799 チェック漏れがこんなことになるとはなあ
/mntにはtempfsをマウントしていないから簡単には使い切れないのが幸いだった
tempfileとrmをループ外へ追い出してみるのと、こんな感じで一時ファイルの場所の移動を試してみます
export TMPDIR=$(mktemp -d)
trap "rm -rf $TMPDIR" EXIT
>>797 言葉足らずで申し訳ない。問題のスクリプはzshスクリプトです
>>797はからかってるか、マジボケかのどっちかだろうよ
trap "command" EXIT
なんて用法があったのか。やはりこのスレは勉強になる
>>801 実装ミスであるなら、どんな仕組みを使っても同じ。
設計手法はそういったミスを抑えるためにもある。
そして設計ミスが生まれる。
おそらくは例外時だろうけど、具体的なバグを聞かないと実装による対処方法は確定しない。
それより一時ファイルを作らない方法でシェルスクリプトを記述するのがいいよ。
パイプやコマンド置換でかなりのところまで行ける。
どうしても一時ファイルが要る場合でも、openしたまま先にrmしとくとかでかなり対処できる。
trap 'rm file' 0 とかで消すのはkill -9 された場合は無理だし。
トラップ一家物語
Cでオブジェクト指向っぽい事するのは例があるけど、
シェルスクリプトでやるのは労力に見合うのだろうか…
Perlのblessされたスカラのリファレンスのようなもの?
そもそも構造体がないからねえ
そんなのより関数作るのが先だろ
HEADER
AA(55)
AA(20)
FOOTER
となっているファイルを食わせて、
HEADER
AA(11)
AA(4)
FOOTER
を吐かせたい。
つまり()内の数値を5で割ったものを吐かせたいんだが、これをshでやるとしたらどういうやり方する?
試しにsed噛ませようと試みたけどあれ演算するのすごいめんどくさそうで
つawk
$ expr "AA(55)" : ".*(\([[:digit:]]\+\)).*"
55
$ echo $((55/5))
11
$
IFS=
sed -e 's/\$/\\$/' -e 's!\(([0-9][0-9]*)\)!(\$((\1/5)))!g' | while read l; do eval echo "\"$l\"";done
sedの中で$((\1/5))なんて出来るのか?
出来ないね。でも
>>813は要求仕様通りに動作する。
816 :
名無しさん@お腹いっぱい。:2014/06/10(火) 01:23:49.76
$$(expr 式)
>>814 sedにshスクリプトを書かせてるわけだね。
今時の sh は bash か ksh93 が標準なのか…
820 :
818:2014/06/10(火) 12:11:58.44
>>819 Solaris8 や HP-UX10 あたりの sh は演算置換できなかった覚えがあるんだけど、
便利になったなあ…
何に準拠してるかではなく、スクリプトを書かせてる発想が大事であって、自分の環境で動かなかったら書き換えればいいだけ。
822 :
810:2014/06/10(火) 12:29:01.86
おお……すごいな
自分の発想が貧困だったことを思い知らされる
ありがとう
eval使うほどの案件じゃない
威張るな
eval使わずに、$((xx)) も使わずに:
while IFS='()' read a b; do
if [ "$b" ]; then
echo "$a(`expr $b / 5`)"
else
echo "$a"
fi
done
>>825 AA(55) や AA(20) の行末に何か文字が入ってしまうとエラーになる
>>819 なら "AA(20) BB(100) CC(65)" とかになっていてもOK
>>826 そんなことわかった上で、要求仕様だけ満たす最小限で書いているのだよ。
悔しいのぅ〜悔しいのぅ〜
ほらよ
sed -e 's/\(["$`]\)/\\\\\1/g' -e 's!\(([0-9][0-9]*)\)!(\$((\1/5)))!g' -e 's/^/"/'
-e 's/$/"/'|while read l; do eval echo "$l";done
う〜〜ん、A("55") だったりすると
>>825 はエラーになるね
>>819 はそのまま出力される…仕様外だからしょうがないのかもしれない
>>830 入力行中に半角¥があると消えちゃうねw
素直にこうじゃいかんの?
while read line; do
case "$line" in
AA\(*\)) echo AA\(`expr "$line" : 'AA(\(.*\))' / 5`\) ;;
*) echo "$line" ;;
esac
done
>>834 AA() の AAは固定という解釈か? BB() とかないの?
>>835 対応は簡単だけど、要求使用外だから別料金
\は厄介だな
IFS=
sed -e 's/\\/!!!rougue_monster!!!/g' -e 's/\(["$`]\)/\\\\\1/g' -e 's!\(([0-9][0-9]*)\)!(\$((\1/5)))!g' -e 's/^/"/' -e 's/$/"/' |while read l; do eval echo "$l";done | sed -e 's/!!!rougue_monster!!!/\\/g'
>>833 >>825 でも "\AA(55)" とかのバックスラッシュは消えちゃうんじゃない
まぁ、バックスラッシュを保存したかったら入力側で "\\\AA(55)" とかして
おけば良いような
そうすると今度は "AA(\55)" が…いや、仕様外だな
841 :
白バラ十字軍:2014/06/10(火) 15:41:26.82
今では殺人事件凶悪事件が起こると創価員かというぐらい
ネットではささやかれる時代になりました。刑務所受刑者の33%は創価員という事実は有名な話ですが、以下を見れば納得ができます
創価員が裁かれる 判決の際 法廷にこだまする「 池 田 先 生 万 歳 !」
◎以下これ以外にまだまだ創価員の犯罪多数あり、書類送検されていないだけであなたの街でも多数すさまじい事件の数が
発生しましたし、まだまだ毎日のように創価員による凶悪事件は発生しているのです!
しかもこれ以外にもTVでも報道された凶悪事件多数あり!。あなたの周りにも潜んでいる。
危険です。危機的状況です。酒鬼薔薇だけではありません。実にたくさんいるのです
あなたの街でも善良な人間のように取り繕い潜んでいるのです。
●宅間守(在日)→大阪 附属池田小学校児童殺傷 創価学会員。大量殺人犯 。8人殺害 15人が重軽傷。悪徳 朝鮮人部落出身。
(悪徳カルト)両親も創価学会員。獄中結婚したが相手の女も創価員。さすが創価員は悪徳な者を好む。あえて結婚する
とは殺人破壊者を賛美、美化、擁護する行為 2004年死刑執行 獄中結婚した女は慰謝料損害賠償払ったのか?被害者に詫びたのか?
宅間は被害者に詫びていない。つまり・・・判決の際 法廷にこだまする「 池 田 先 生 万 歳 !」ということ
日本の犯罪史上、稀に見る大事件
●畠山鈴香 (在日)→秋田県児童連続殺害事件 創価学会員。悪徳。(悪徳カルト)
●斉藤勇太 →JR取手駅前バス無差別殺傷事件 創価学会員。悪徳。(悪徳カルト)
●酒鬼薔薇聖斗→ 東慎一郎(在日)神戸の首切り魔で酒鬼薔薇聖斗 創価学会員。神戸の首切り魔。生首を校門に飾る。悪徳2人殺害。
元在日朝鮮人。両親も創価学会員(悪徳カルト)
●福田孝行(在日)→山口県母子殺害 殺害後屍姦、乳児も殺害 創価学会員。悪徳(悪徳カルト)
●阿部隆 →長野母子バラバラ殺人事件(平成元年)船橋市幼児バラバラ殺人事件 千葉県船橋市の熱心な創価学会員・A・A子さんと長男
のHちゃんが、同じく学会員である夫のA・Tに殺された。動機は生活苦。バラバラにされた死体が聖教新聞に包まれ、長野県の山中に捨
てられていた 悪徳(悪徳カルト)
お前らこういう問題好きすぎだろww
分かるけどさ
>>843 あくまでコマンドラインで操作するってだけで
シェルスクリプト関係なさそう
つーかこういうツールって大抵CLIだからわざわざタイトルに書かなくてもいいような
素直にperlでいいじゃんと思った俺は負け組か。。。
>>845 しかも Perl のワンライナーの方が速いっていう
せやろか?
速さより早さ。
早さより可読性
っていうのはスレ違いかな
>>844 関係なさそうどころか、普通にIPythonとR使いますって書いてある
男は度胸!何でもためしてみるのさ
問:下記のようなテキストファイルがある
>__BEGIN__
>NAME:xxx
>...
>STYLE:yyy
>...
>__END__
>__BEGIN__
>NAME:aaa
>...
>STYLE:bbb
>...
>STYLE:ccc
>...
>__END__
>__BEGIN__
>..
BEGIN-END間を1ブロックとして、1ブロック内にNAMEが1つ、STYLEが1つ以上。
1ブロックの情報を「NAME:STYLE,STYLE,,,,」というように1行にまとめて整形するようなスクリプトを考える。
全行数が数百万行、ブロック数は数千ほどあるとして、現実的実行時間で収まる事。
__BEGIN__は最初の1つ以外はすべて__END__の直後にあるとし、NAMEは__BEGIN__の直後に出現、STYLEの位置はブロック毎に異なるとする。
暇潰しにどうぞ
>>852 sedでいらない行消してNで適当にくっつけて改行を,に変えてちょっと整形すればいいんじゃね?
BEGIN{FS=":"}
$1=="NAME"{n=$2}
$1=="STYLE"{s=s$2","}
$0=="__END__"{sub(/,$/,s);print n":"s;s=""}
awkすげぇな……
うーん、もっとコンパクトに書きたい……
egrep '^(NAME:.*|STYLE:.*|__END__)$' | sed -E -e :begin -e N -e 's/\n__END__$/&/' -e tend -e bbegin -e :end -e 's/^NAME://' -e 's/\nSTYLE:/:/' -e 's/\nSTYLE:/,/g' -e 's/\n__END__$//'
egrepなくして冗長も減らしてみた
sed -e 's/^__BEGIN__$//' -e :B -e N -e 's/\nNAME://' -e 's/\nSTYLE:/,/' -e tB -e 's/\n__END__$//' -e tE -e 's/\n.*//' -e bB -e :E -e 's/,/:/'
856だとメモリ詰め込みまくりでなんだかなぁって思ったけど、
857だとうまくいきそうだな
実行時間どんなもんやろか
>>857もすごいが、個人的には
>>854が好きだな
必要最低限のことしかしてない感じと可読性の高さが気に入った
何より仕様変更に強そう
alias でもなく pushd/popd でもなくて、もっと簡単にディレクトリを登録して呼び出せるような方法ってないですかね?ブックマーク(?)みたいに
ただし bash 限定で
861 :
名無しさん@お腹いっぱい。:2014/06/15(日) 04:10:21.09
symlinkでいくね?
aliasで十分すぎるぐらい簡単な気がするんだが……
シェル勉強中だがesacみて吐き気がした
fiはfinish ifか何かの遊び心としてもこれはちょっと……
この程度で吐き気してたら先が思いやられるね
for … rof
while … elihw
とかも出てくるから慣れようねw
866 :
名無しさん@お腹いっぱい。:2014/06/15(日) 18:50:25.87
あ.そう
od が無ければ、algol にならって、do list; od だったのだろうか。
if .. fi や case ... esac のようなのと
do .. done がごっちゃになってるのは美しくない!
みたいなこと言ってる人見たことあるけど割とどーでもいいな
do .. done系は全部ループやしそれ以外は反転ってルールにしたんだろうね
esacは確かにキモいがだからと言ってendcaseとかやられてもうーん
シェルスクリプトに何を求めて勉強してんだ。
esacが嫌な人はCシェル使えばいいと思うよ
>>854のawk
最後のsub(/,$/,s);ってsub(/,$/,,s);の書き間違いかなと思うんだが
sub(/,$/,,s)じゃなくてsub(/,$/,"",s)か
勘違いだったらハズカシィ
セミコロンで区切るのだってキモいだろ
esacとたいして変わらん
C言語から学び始めた俺にとっては至極自然
とはいえサブシェルを{}で開くと違和感バリバリだが
>>876 サブシェルは () だぞ。{ ;} は同じシェルの単なるグルーピング。
キモいと言ってるのはcase(switch)文をbreakする仕組み自体のことじゃなく、
そのbreakを ;; という記号で表すことについて言ってるんだけど。
改行の代わりにコマンドを ; で区切る話じゃないのか?
879 :
876:2014/06/19(木) 15:50:23.77
すまん
>>878のつもりでセミコロンの話解釈してたけどcaseの中身の話か
確かにありゃキモいな
そしてサブシェル勘違いorz
findの-execのセミコロン「ゆ…許された」
esacも;;も気にならんけど、(と対称にならないcaseのパターン指定はダメだ。
bashだと、
case $var in (hoge) echo hoge;; esac
とか書けるんだ。
なんか書き込みがずっとないからなんか書いてみよう
--
あるファイルに、
1
2
3..
という具合に、改行区切りで昇順に数字が書き込まれているとする
しかし、ファイル末尾の数値と行数が合わない為、どこかで数値が欠けている、もしくは重複していると予想される
ファイル内部は昇順ソート済みとして、重複・欠損している数値を洗い出す効率の良い仕組みを考える
shでもperlでもなんでもどうぞ
awk 'NR!=$1{print NR}'
i=1; while read line; do [ "$line" != $i ] && echo $i; i=`expr $i + 1`; done
for((i=1; ;i++)){ read l||break;case $l in $i);;*)echo $i;;esac;}
exec 3<&0;yes ''|cat -n|while read f <&3;do read i;[ "$f" != $i ]&&echo $i;done
cat -n|while read a b; do case $b in $a);;*)echo $a;;esac;done
遅レスだが、
>>860については、俺はシェル変数使ってるな。
rcファイルでd=/path/nameとしておいて ls $d とか。
ホーム直下に一文字シンボリックリンク作るより文字数は少なくて済む。
ファイル名をnumとして
diff -y --supress-common-lines <(seq 1 `tail -n1 num`) num
他のがぱっと分からんけど、
>>884って1回ズレたとこ見つけたらそれ以降全部吐かない?
えらい邪魔なような
目的が差異の確認だしdiffが一番スマートな印象だなぁ…出力形式も変更が効くし
>>890 だと標準入力から読めない。one passで実行できない。
one passが何かはよく知らないんだが、
・ファイルに書き込まれたものをチェックする前提がある=標準入力使う必要がない
・重複、又は欠損がある=複数、両方ある場合に全て検出するのが理想
というのを考えると、diffが一番いい答えを返してくれそうな気がする
>>884は確かにシンプルなんだが、ファイルの比較的先頭のほうが狂ってた場合、それ以降を全部出力しちゃうっていう点で微妙な気もする
>>895 headすればいいじゃん。
そんなに頻繁に使うものとは思ってないので、書きやすい方がいいと思いました。
897 :
名無しさん@お腹いっぱい。:2014/06/24(火) 17:31:03.08
>>890 だと、
もしファイルの最終行が間違っていて 最終行の内容が 1 とかだったら、
どの行が違っているのか全然チェックできない。
シェルを書く際の注意事項があります。
コンピュータのCPUが何ビットであるか調ベておく事が大切です。
32ビットCPUを登載したコンピュータには、
32ビット用のシェルを書くこと。
64ビットCPUを登載したコンピュータには、
64ビット用のシェルを書くこと。
これを間違えればシェルが動きません
自閉症あらわる
シェルの意味が分かってないんじゃないの?
いつもの改変コピペ君。
相手しちゃいかん。
--suppress-common-lines のスペルが違ってたり、
プロセス置換使って互換性無いのに backquote 使ってるのも気になるが、
diff がいいんじゃないの。
重複、欠損が1つとは限らないし、ワンライナーでなくスクリプトの話でしょ?
あと、yes '' | cat -n とかおもしろい。
改行区切りで昇順なのに、
>>897 の "最終行の内容が 1" って突っ込んだら負けなのか?
>>883 $ cat a.txt | tee >(uniq -d) >(uniq | awk 'NR!=$1{for(i=NR;i<$1;i++){print i};NR=$1++}') &>/dev/null
moreutils の pee を使う場合
$ cat a.txt | pee "uniq -d" 'uniq | awk '\''NR!=$1{for(i=NR;i<$1;i++){print i};NR=$1++}'\'''
peeとかすごいネーミングw
$ seq 1 `cat a.txt | wc -l` > tmp.txt; diff a.txt tmp.txt; rm tmp.txt
とかでよくね
添付ファイルとか品質低下し杉
しばらく書き込みないと思ってたのに反応すごいな
>>902の「互換性ないのに`使ってる」っていう点なんだが、
プロセス置換の記述の中で``って使えない環境もあるのか?
プロセス置換自体よくわかってないとこあるからちょっとあれだが
プロセス置換と``が同時に使えない場合でも
>>905みたいなのはさすがにな……
出遅れたが、またawkで
awk '{if($0-p!=1)print NR,p,$0;p=$0}'
この手のお題は入出力例が欲しいなぁ
>>852 出遅れどころじゃないけど、NULつけてLFと交換するとか:
sed -n -e 's/^NAME:\(.*\)$/\x00\1:/p' -e 's/^STYLE:\(.*\)$/\1,/p' | tr '\000\n' '\n\000'
914 :
名無しさん@お腹いっぱい。:2014/06/25(水) 03:31:58.38
ゆえとたまきんのおしっこ直飲みしたい
916 :
名無しさん@お腹いっぱい。:2014/06/25(水) 09:48:52.03
渋谷に集まったサポーターが痴漢してるわけじゃなくて、
人の多いところに痴漢常習者が集まっただけ。
ジャニのコンサート会場の最寄駅なんかも沢山いる。
>>907 クドくなるので
>>902 では文章を削るばかりだったが、
もっと言葉を選べば良かった。互換性でなく portability とかの方が適切だったかも。
>>890 では、zsh bash ksh の機能であるプロセス置換を使っているので、
portability は既に失われている。
この為、back quote はあえて使う必要が無い。
スペルミス同様大した事じゃあ無いが、何で back quote 使ってるの?と気になった。
以下、念の為の補足。
参考他で議論されている通り、一般的に back quote は、
公式には非推奨ではないものの、使わない様にしたい古いやり方。
`...` は、POSIX 非互換のとても古い Bourne shell でのみ必要なレガシーな構文。
ただし、このスレは Bourne Shell(/bin/sh) がデフォルトで、heirloom sh がどうのと
>>1 に書いてあるので、portability を考え back quote を使うか、特記して
dollar parens を使用する事が望ましい。
個人的には POSIX デフォにしたいですが。
参考
Have backticks (i.e. `cmd`) in *sh shells been deprecated?
http://unix.stackexchange.com/questions/126927/
>>918 890のbacktickは必要じゃないの?
というかコマンドの出力を文字列で参照するとき、backtickで括るのは珍しくないでしょbashでも
入れ子にするときどう書く?
2行に分ける
バッククォートの入れ子は基本だな。新入社員のテストで良く使う。
バッククォートの3重入れ子までできて一人前。$( )なんかに逃げるのは半人前。
cshでは入れ子にできないことを知って捨てる決意をした25年前
漏れutilsってところが、また、そそるよな
>>918 なるほど、/bin/shじゃ動かないのになんで/bin/shで使うバッククォート使ってるんだって話だったのか
個人的に$( )が使い慣れなてないだけだったんだけどね
bashなら問題なく動くから普通に記述してしまった
>>922 さすがにバッククォートの3重入れ子とかするぐらいなら$( )使えよって思う
一応出来たけど汚い
参考の様な意見が一般的だと言うだけで、ポータビリティが関係ないスクリプトでも、
`cmd` で書きつづける人もいるでしょうね。
たとえ、Obsolete and deprecated syntax とか legacy とか言われても。
少なくとも、
>>919 >>921 >>922 は back quote なわけでしょ?
無用な議論するつもりは無いけど、しかしながら、
back quote を肯定する理由が有るなら、参考までに聞いてみたい。
何故に back quote を使っていますか?
>>924 ダメ押しわろた
しかし、peeってw 分かった上であえて、peeなんだろうな。き、汚過ぎるわ
slとかtacみたいな、ひねりの効いたネーミングにはならなかったのかな
>>919 いや、bash で backtick は、初心者か、
最近まで商用 UNIX さわってて、そのままの人とかじゃないですか?
ある程度、O'Reilly とか本を読んだり、ネットで知識を漁ったりすれば、backtick は無いはず。
ちょっと、検索しておいたのを、挙げておきます。
1. Classic Shell Scripting: Hidden Commands that Unlock the Power of Unix
http://books.google.co.jp/books?id=J9WbAgAAQBAJ p156 $(...) を指して、
This style is recommended for all new development,and it is what we use in many of the examples in this book.
2. Learning the Korn Shell, 2nd Edition
http://oreilly.com/catalog/korn2/chapter/ch04.html The syntax of command substitution is:
$(Unix command)
...
(For backwards compatibility, the Korn shell supports the original Bourne shell (and C shell)
command substituion notation using backquotes: `…`. However, it is considerably harder to
use than $(…), since quoting and nested command substitutions require careful escaping.
We don't use the backquotes in any of the programs in this book.)
>>927 バッククオートならどのシェルでも使えるからだよ
bash専用だから$()使ってもいい、という考えは別に否定しない
見栄え重視。
入れ子にするなら$( )のほうが綺麗になるが、単発ならバッククォートのほうが見やすく思える
昔からやってる人間なら 新しい記法は知ってるけど慣れで昔のままってだけだよね
議論したくないとか言って古い人間の習慣をただdisってるだけだな
人様に見せるコードなら着飾るけど
ワンショットの使い捨てなんてのは
各々書きやすいように書けばいいと思う
逃げられたな。
>>934 ありがとう。古い人間の習慣か。
バッククォートは一般的に、使わない様にしたい古いやり方だとは思うけど、参考を紹介する位。
議論しても平行線だろうし、人それぞれだなあと思ったよ。
それに、このスレはバッククォートがデフォだし。
>>936 けんか腰だな。
逃げられたな。(170cm 60kg) <- 言いそう
逃げられたな。(190cm 90kg) <- 言わなそう
逃げられたな。(178-75-32)
>>939 誰だよw
逃げられたな。(163*90*53)
941 :
909:2014/06/25(水) 23:32:22.49
>>910 {if($0-p!=1){print NR,p,$0}
p=$0}
なら分かりやすかった?
>>909の;はif文そのものを終わらせている
上記()の後の{}は中身が単文なので必須ではない
もし続けるならawkスレで
>>941 おおわざわざ解説ありがとう
やっぱシンプルかつ欲しい情報が的確に手に入る感じで好きだなこれ
>>942 その点が明示されてないから好きにやれよとね
その点てのはなんちゃら性とかいういわば目的ね
決定版は
>>909 だけど、性懲りもなく moremore pee でやってみる
とは言え、頭に D(uplicate)、S(kip)を付けただけだけど
$ cat a.txt | pee \
"uniq -d | sed -r 's/.+/D &/'" \
'uniq | awk '\''NR!=$1{list="S";for(i=NR;i<$1;i++){list = list " " i};print list;NR=$1++}'\'''
しかしawkが思った以上に優秀だな
>>854といい
>>909といい、フィールド抽出だけにしか使ってなかったawkがこうまで活躍するとは思わなんだ
せ、sedだってチューリング完全だし、数字の計算くらいかけるはずだよ……
awkすごいな あこがれちゃうな