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

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

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。2009/01/29(木) 06:54:48
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。


□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashなので特に注意。
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でそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。

前スレ落ちたみたいなのでリンク省略。
0252名無しさん@お腹いっぱい。2009/02/22(日) 00:34:27
>>244
だからlgrepがあるつーの。
0253名無しさん@お腹いっぱい。2009/02/24(火) 23:14:27
シェルの中でexpectを使ってwinにtelnetしてbatを実行してるんですが、
当然文字コードが違う(EUCとSJIS)ので化けます。

LANGを途中変えても変わらないです。(ターミナルのせいだと思いますが)

化けないようにできますか?
0254名無しさん@お腹いっぱい。2009/02/24(火) 23:19:46
>>253
・標準出力にパイプで | nkf -Se をかます
・ktermをSJISモードで開く

好きな方選べ
0255名無しさん@お腹いっぱい。2009/02/24(火) 23:30:46
| iconv -f EUC-JP -t Shift_JIS
0256名無しさん@お腹いっぱい。2009/02/24(火) 23:42:35
シェルってゆうな。クズ。
0257名無しさん@お腹いっぱい。2009/02/25(水) 06:36:32
>>255
それ、-t と -f 逆だろ。
0258名無しさん@お腹いっぱい。2009/02/25(水) 10:09:23
>>251 ほとんどすれ違いネタになっていたのにありがとうございます
grep -f - -rl .
後の日本語入力→改行→ctrl+dで探索スタートできました。(xterm)
0259名無しさん@お腹いっぱい。2009/02/25(水) 15:12:52
ディレクトリ内にひとつしかファイルorディレクトリがない場合に
コマンドを実行しようと思い、

for dir in `find . -type d -maxdepth 1`
do
    test $(ls -1 $dir | wc -l) -eq 1 && command
done

このように書いてみたのですが、ディレクトリ名が空白で区切られて
しまいうまく動きません。
どのように対処したらいいでしょうか?
0260名無しさん@お腹いっぱい。2009/02/25(水) 15:17:13
find . -type d -maxdepth 1 | while read dir
do
test $(ls -1 "$dir" | wc -l) -eq 1 && command
done
0261名無しさん@お腹いっぱい。2009/02/25(水) 15:28:47
>>259

find . -maxdepth 1 -type d \
-exec sh -c 'for d;do [ $(ls "$d"| wc -l) -eq 1 ] && command; done' dummy {} +
0262名無しさん@お腹いっぱい。2009/02/25(水) 16:21:38
>>260
ありがとうございます。readを使うと良いんですね。
無事目的の動作をさせることができました。

>>261
ありがとうございます。
-execはあまり使ったことがないのですが、最後の
done' dummy {} +
の意味がいまいち理解できませんでした。
よろしければ教えていただけますか?
0263名無しさん@お腹いっぱい。2009/02/25(水) 16:26:36
readを使うと、\ を含むディレクトリ名が読めないとか、
(途中じゃなく)頭にスペースが付いてるディレクトリ名が読めないとか
問題が残るんだな。
その点も含めて解決するとなると、>>261 の解になる。
0264名無しさん@お腹いっぱい。2009/02/25(水) 17:34:24
>readを使うと、\ を含むディレクトリ名が読めないとか、
>(途中じゃなく)頭にスペースが付いてるディレクトリ名が読めないとか

IFS= read -r
0265名無しさん@お腹いっぱい。2009/02/25(水) 17:36:23
>>264
read -r は bash依存。

で、それやっても「改行入り」ディレクトリ名が正しく処理されない。
結局 >>261 一択。
0266名無しさん@お腹いっぱい。2009/02/25(水) 17:48:53
read -r は posix じゃね?
0267名無しさん@お腹いっぱい。2009/02/28(土) 18:54:04
基本的なことかも知れませんが、
キーボードを読んで分岐するバッチはどう書けば医院でしょうか?
0268名無しさん@お腹いっぱい。2009/02/28(土) 19:04:18
バッチならset /pですね。でも板違いなので出てってください。
0269名無しさん@お腹いっぱい。2009/03/01(日) 02:23:56
>>268
MSDOSのバッチスクリプトしか知らない人?
バッチって、バッチ処理等の普通名詞だろう
0270名無しさん@お腹いっぱい。2009/03/01(日) 03:26:52
パスワードがかかってないzipファイルにパスワードをかけていきたいんですが、
そもそもパスワードがかかってないか判定するすべはありますか?
0271名無しさん@お腹いっぱい。2009/03/01(日) 06:54:24
>>270
unzip -Zv *.zip | grep 'file security status'
0272名無しさん@お腹いっぱい。2009/03/01(日) 08:06:08
cronもatも使えない環境で、指定日時時刻にシェルを実行するバッチって書けますか?
0273名無しさん@お腹いっぱい。2009/03/01(日) 11:17:51
>>269
普通名詞のバッチ処理はユーザーからの入力待ちは行えない。必要な入力データは
あらかじめ用意しておく処理。対話処理とは対極的なもの。
ユーザーからの入力によって処理を変えたい「バッチ」というならMSDOSのバッチに他ならない。
0274名無しさん@お腹いっぱい。2009/03/01(日) 11:20:52
>>272
指定時刻までの時間を計算してsleepする。
0275名無しさん@お腹いっぱい。2009/03/01(日) 11:27:52
>>274
それはわかってますよ。その具体的なシェルを質問してるんですが。
0276名無しさん@お腹いっぱい。2009/03/01(日) 11:29:40
echo -n 'xx時xx分xx秒までの時間を入力してください '
read t
sleep $t
command
0277名無しさん@お腹いっぱい。2009/03/01(日) 11:32:04
すみませんが、詳しくご存知の方のみ御回答をお願いします
0278名無しさん@お腹いっぱい。2009/03/01(日) 12:34:37
>>277
お前、何様のつもり?
0279名無しさん@お腹いっぱい。2009/03/01(日) 12:42:54
こういうのがはやってるみたいよ
0280名無しさん@お腹いっぱい。2009/03/01(日) 13:14:31
ttp://pc11.2ch.net/test/read.cgi/db/1057136328/188

これってシェルスクリプトで出来るんですか?
0281名無しさん@お腹いっぱい。2009/03/01(日) 16:28:03
>>277 は多分質問者じゃない。
こういう荒らしを楽しんでる奴が最近いる。
0282名無しさん@お腹いっぱい。2009/03/01(日) 18:03:41
そらできるよ
0283名無しさん@お腹いっぱい。2009/03/01(日) 19:27:53
bashとawkって書いてあるじゃん
0284名無しさん@お腹いっぱい。2009/03/01(日) 20:10:39
bashはわかりますが、awkって何ですか? bashのプラグインみたいなものとは思いますが
0285名無しさん@お腹いっぱい。2009/03/01(日) 20:44:21
その認識でおk
0286名無しさん@お腹いっぱい。2009/03/01(日) 21:02:50
工エエェ(´д`)ェエエ工
0287名無しさん@お腹いっぱい。2009/03/01(日) 21:03:02
bashとawkでGUIができるの?
0288名無しさん@お腹いっぱい。2009/03/01(日) 23:21:15
久々に笑った。
まさかbashのプラグインと来るなんてねえ。
0289名無しさん@お腹いっぱい。2009/03/02(月) 09:25:51
>>287
GUI とhttp通信は別コマンドじゃないかな
awkを書いたのはCSVのparseに使ってるからだろうね
0290名無しさん@お腹いっぱい。2009/03/02(月) 15:07:18
すみませんが、まったくの素人の方のみ御回答をお願いします
0291名無しさん@お腹いっぱい。2009/03/03(火) 10:58:08
$ echo abcd def | read a
$ echo $a


echo の結果を read では変数にセットできない?
0292名無しさん@お腹いっぱい。2009/03/03(火) 11:05:13
できるよ。
ただ、| のうしろはサブシェルになるので、
セットしてすぐサブシェルが終了して忘れるだけ。

echo abcd def | { read a; echo $a; }

ksh だとサブシェルにならないので↑のようにしなくてもふつーに動く。
0293名無しさん@お腹いっぱい。2009/03/03(火) 11:43:30
なるほど、ありがと。
大人しくバッククォートで実行の結果使います。
0294名無しさん@お腹いっぱい。2009/03/04(水) 23:31:09
cshのこと聞いてもいいですか?
0295名無しさん@お腹いっぱい。2009/03/05(木) 00:18:50
>>1を読んでて答える人がいればいいんじゃない?
俺はcshは分からんが。
0296名無しさん@お腹いっぱい。2009/03/05(木) 02:03:59
変数の最後入っている改行コードを取り除く方法ってありますか?
Perl の chomp をシェルでやりたいのです。
0297名無しさん@お腹いっぱい。2009/03/05(木) 02:18:18
b="`echo $a`"
0298名無しさん@お腹いっぱい。2009/03/05(木) 02:21:31
b="$(printf "%s" "$a")"すると連続した空白も保存
0299名無しさん@お腹いっぱい。2009/03/05(木) 06:46:31
>>297 だとスペースが保存されないし、* とかの特殊記号が展開される。

b=`echo "$a"`
で桶。
0300名無しさん@お腹いっぱい。2009/03/06(金) 00:52:11
>>295
ではだめもとで。

配列の
array=( "a 1" "b 2" "b 3")
をforで1要素づつ使いたい場合

for d in ${array[@]}
do
echo $d
done

とかできますよね

これをcshでやること可能ですか?
0301名無しさん@お腹いっぱい。2009/03/06(金) 01:36:18
間違えた
for d in "${array[@]}"
do
echo $d
done

こうです。
0302名無しさん@お腹いっぱい。2009/03/06(金) 06:41:00
foreach i ($array)
echo $i
end
だろ。
0303名無しさん@お腹いっぱい。2009/03/06(金) 06:48:04
csh(笑)の質問はこっちでやれ
http://pc11.2ch.net/test/read.cgi/unix/1094041299/

>>302
それだと、要素の中のスペースで分割されてしまうからダメ。
例: "a 1" が a と 1 に別れてしまう。
0304名無しさん@お腹いっぱい。2009/03/06(金) 09:42:48
そんなこと言うならbash()笑の質問もこっちでやれってことになるぞw
http://pc11.2ch.net/test/read.cgi/linux/1210999497/
0305名無しさん@お腹いっぱい。2009/03/06(金) 22:26:43
>>300
cshなら配列使えばいいのでは?

#!/bin/csh -f
set a = ("a 1" "b 2" "c 3");

set i=1
while ( $i <= $#a )
   echo $a[$i]
   @ i = $i + 1
end
0306名無しさん@お腹いっぱい。2009/03/07(土) 00:49:25
set name = value
とかイコール前後にスペース付けられるあたりはcsh悪くないよね

というかスペースを許さないbashの代入がちょっとどうかと思う。
0307名無しさん@お腹いっぱい。2009/03/07(土) 01:10:08
なぜそこでbash
0308名無しさん@お腹いっぱい。2009/03/07(土) 03:17:01
とつぜんbashがきたので・・・
0309名無しさん@お腹いっぱい。2009/03/07(土) 07:01:04
>>306
算術式ならbashでもスペースを入れられるよ。

((i = 123))
echo $i
0310名無しさん@お腹いっぱい。2009/03/08(日) 04:05:42
(())ってなんなの?
0311名無しさん@お腹いっぱい。2009/03/08(日) 05:48:05
ま○こ
0312名無しさん@お腹いっぱい。2009/03/09(月) 19:53:57
まi = 123こ
echo $i
0313名無しさん@お腹いっぱい。2009/03/10(火) 07:44:38
sh, bashでシェル変数の値を変数名とするシェル変数を定義して
代入したいのですがどうすればよいでしょうか?
eval "$A=B"

eval "$A"=B
と書くと、意図通りに代入と判断されるシェル(最近のLinuxのbashやSolarisのsh)も
有ればコマンドと判断されてcommand not foundとなってしまう
シェルもあって、困っています。
0314名無しさん@お腹いっぱい。2009/03/10(火) 08:24:35
>>313
一般的には、代入する値のスペースや記号の解釈を避けるには、

eval $A=?''代入する値'?'

と書いておけば桶。evalを含めた2回の解釈を回避するために、
シングルクォートを2回ネスティングする。
$Aの方は、中身は単純な変数名が入っているため、
裸の $A のままクォートしなくても桶。

Solarisのshで動くならそれが標準と考えて良い。
これで動かないようなシェルは捨てるべき。
0315名無しさん@お腹いっぱい。2009/03/10(火) 08:27:12
>>313
わ、なぜかこの環境から書き込むと、
半角の\が?に化ける。(なんで?)
>>313 の?はバックスラッシュに読み変えてね。
0316名無しさん@お腹いっぱい。2009/03/10(火) 08:59:21
>>313
具体的にどのシェルか言えよ
そのときだけ"$A"にスペースが入ってんじゃないの?
0317名無しさん@お腹いっぱい。2009/03/10(火) 18:05:12
シェルスクリプトってOOじゃないんでしょ?
ダサっ
0318名無しさん@お腹いっぱい。2009/03/10(火) 18:37:45
>>313
困っています、じゃあ独り言にしかなってないぞ。
動かない場合の代わりの方法が欲しいのか、
ネタを流してるのかハッキリしろ。
0319名無しさん@お腹いっぱい。2009/03/10(火) 20:10:54
last(1)を去年の11月から今日まで出したいのですがどうすれば
いいでしょうか。
0320名無しさん@お腹いっぱい。2009/03/10(火) 20:30:06
cat /var/log/wtmp.3 /var/log/wtmp.2 /var/log/wtmp.1 /var/log/wtmp.0 /var/log/wtmp >/tmp/wtmp
last -f /tmp/wtmp
rm -f /tmp/wtmp

場所が違えば適宜探すこと。
圧縮されてたら適宜伸長すること。
11月の分が存在しなければ諦めること。
0321名無しさん@お腹いっぱい。2009/03/11(水) 02:00:46
>>314-315
ありがとうございます。
が、試してみたところエラーとなりました。

XX=YY形式の設定ファイルをIFS="="として、
while readで読み込んで、環境変数XX=値YYとしています。
whileブロックの外ではエラーがでないので、
IFS="="が悪さをしているのではないかとふと思いつきました。
明日試してみます。

>>316,318
bash3.2.25です。
0322名無しさん@お腹いっぱい。2009/03/11(水) 06:29:23
>>321
エラーになってあたりまえだ。

IFS="=" にすれば、コマンド上では = が消えてしまう。
XX=YY は、実際には XX YY という風に実行され、エラーになる。

これは、「シェル変数の値を変数名とするシェル変数を定義して代入」
以前の問題。

「シェル変数の値を変数名とするシェル変数を定義して代入」の問題なら、
>>314-315 の回答で合ってる。

あと、bash-3.2.25かどうかは関係ないと思うぞ。
エラーが出るなら他のシェルでもエラーになるはず。
0323名無しさん@お腹いっぱい。2009/03/11(水) 09:45:54
Windows PowerShellはOOなのに
シェルスクリプトはOOじゃないんだよね
時代遅れだね
0324名無しさん@お腹いっぱい。2009/03/12(木) 07:21:25
>>323
PowerShell は最近生まれたものなんだから当然だろ。
比較するなら PowerShell と同時期に生まれたシェルと比較しろ。
0325名無しさん@お腹いっぱい。2009/03/14(土) 01:53:46
jpgファイルのサイズを知りたいんですが、調べられますか?
0326名無しさん@お腹いっぱい。2009/03/14(土) 02:09:29
はい
0327名無しさん@お腹いっぱい。2009/03/14(土) 02:14:51
>>324
彼はLinux板のシェルスクリプトのところでも同じことを書いてたから。
0328名無しさん@お腹いっぱい。2009/03/14(土) 02:20:53
>>325
imagemagickのidentifyコマンド
0329名無しさん@お腹いっぱい。2009/03/14(土) 12:03:01
ls -lとかじゃないのか。
0330名無しさん@お腹いっぱい。2009/03/14(土) 12:32:29
echo "jpgファイル" | wc -c
0331名無しさん@お腹いっぱい。2009/03/14(土) 23:02:45
>>328
ありがとうございます。できました。

>>329
>>330
すいません。サイズという表現微妙でした。
解像度?1280x1024とかの値の話でした。
0332名無しさん@お腹いっぱい。2009/03/17(火) 22:56:18
かなりてきとーだけど。

while read l; do
for w in $l; do
type $w > /dev/null 2>&1 && echo $w
done
done < (ファイル) | sort | uniq
0333名無しさん@お腹いっぱい。2009/03/18(水) 19:31:29
>>325 >>331 X環境ならば
xfceのthunarだと画像ファイルを選ぶとステータスバーにサイズを表示する。
あとImageMagickいれるならば関連付けでdisplayにすれば良い
あとはperlなりcなりでperlmagickなりmagickwandなりでやりたい放題。

但しexifはdisplayでは対応しているけれどImageMagickのライブラリーは対応していないので
libexifとかexiftool入れると良いと思う
0334名無しさん@お腹いっぱい。2009/03/18(水) 19:32:16
>>333 つまりこのスレ的にはexiftoolの返しをいかに削るかということだと思う
03353282009/03/18(水) 20:35:04
つ identify -verbose
0336名無しさん@お腹いっぱい。2009/03/19(木) 01:52:23
削るとかよりも素直に
WIDTH=`identify -format '%w' image.jpg`
HEIGHT=`identify -format '%h' image.ipg`
じゃない?
0337名無しさん@お腹いっぱい。2009/03/21(土) 00:05:33
>>336 元質問者の調べる楽しみを奪っちゃダメだよ。 >>335くらいでとどめておくのが良い
exifに手を出せばいろいろおもしろいんだから、すぐにmanとかで分かるし。
ijgのおまけの返しから削る手だってある。
ノーヒントならともかく「わかった」という喜びを与えてあげよう
それにshell script的には削って置換した方がおもろい。
選択肢が多く汎用性のあるものはいかにおもろいかが重要。
0338名無しさん@お腹いっぱい。2009/03/22(日) 04:07:52
shcでできたCソースからshに戻すというのは楽しいですか?
0339名無しさん@お腹いっぱい。2009/03/22(日) 08:11:40
>>338
俺がお前に聞きたいわ。
0340名無しさん@お腹いっぱい。2009/03/22(日) 23:38:38
shcってechoはsystem("echo");とかに変えるんだろうか?
0341名無しさん@お腹いっぱい。2009/03/25(水) 18:48:49
過去ログ見終わって今来た。ふぅ。

cshでさ、cshrcで
set path = (${path} ${TOMCAT_HOME}/bin)
setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:${TOMCAT_HOME}/lib
setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:${TOMCAT_HOME}/ROOT/WEB-INF/classes
setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:${TOMCAT_HOME}/ctx/lib:${TOMCAT_HOME}/jdbc/lib
って設定してて、気がつくと、
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/app/tomcat/webapps/bin:/opt/app/tomcat/webapps/bin:/opt/app/tomcat/webapps/bin:/opt/app/tomcat/webapps/bin:/opt/app/tomcat/webapps/bin
LD_LIBRARY_PATH=:/opt/app/tomcat/webapps/lib:/opt/app/tomcat/webapps/ROOT/WEB-INF/classes:/opt/app/tomcat/webapps/ctx/lib:/opt/app/tomcat/webapps/jdbc/lib
:/opt/app/tomcat/webapps/lib:/opt/app/tomcat/webapps/ROOT/WEB-INF/classes:/opt/app/tomcat/webapps/ctx/lib:/opt/app/tomcat/webapps/jdbc/lib
:/opt/app/tomcat/webapps/lib:/opt/app/tomcat/webapps/ROOT/WEB-INF/classes:/opt/app/tomcat/webapps/ctx/lib:/opt/app/tomcat/webapps/jdbc/lib
:/opt/app/tomcat/webapps/lib:/opt/app/tomcat/webapps/ROOT/WEB-INF/classes:/opt/app/tomcat/webapps/ctx/lib:/opt/app/tomcat/webapps/jdbc/lib
みたいなことになってるけど、重複した同じパスの解消ってスクリプトで出来る?
なんだか検索で遅くなりそうだが、気にしないが現実的?
0342名無しさん@お腹いっぱい。2009/03/25(水) 21:04:54
cshなんて使わないのが現実的
.cshrcでは setenvしない(setenvは .loginでする)のが現実的
setenvする場合でも、以前の値が蓄積するような書き方はしないのが現実的

cshの話題は
http://pc12.2ch.net/test/read.cgi/unix/1094041299/
に書くのが現実的
0343名無しさん@お腹いっぱい。2009/03/26(木) 00:23:22
csh って何回も打つからそうなるんじゃない?
それならshでも同じことでしょ

存在しないコマンド打った場合はエラーが帰るのが多少遅くなりそうだけど・・

気持ち悪ければ、「;」を改行に変えて、sort -u して「;」戻して新たにPATHに突っ込めばよいのかもしれんけどそうすると元の順番と変わるなぁ
0344名無しさん@お腹いっぱい。2009/03/26(木) 07:27:35
>>343
>それならshでも同じことでしょ

なんでやねん。アフォかw

shの .profile は「ログインシェル」しか読まない。
shって何回も打っても二重登録されない。
0345名無しさん@お腹いっぱい。2009/03/26(木) 07:41:07
いや.shrcならさ
0346名無しさん@お腹いっぱい。2009/03/26(木) 07:51:23
>>345
はぁ? .shrc なんてファイル何者?

少なくとも/bin/shはそんなファイルを読まない。
ash bash zsh ksh も .shrcなんてファイル読まないぞw
0347名無しさん@お腹いっぱい。2009/03/26(木) 08:00:36
cshには .login ってファイルなかったっけ
0348名無しさん@お腹いっぱい。2009/03/26(木) 08:04:57
>>347
>>342 が回答済み
0349名無しさん@お腹いっぱい。2009/03/26(木) 14:58:19
>>341
普通に使ってたら、そんなことは起きない。
0350名無しさん@お腹いっぱい。2009/03/26(木) 23:52:39
.shrcってないんだ・・
bashしか使わんから.bashrcみたいにあると思い込んでいたよ
0351名無しさん@お腹いっぱい。2009/03/27(金) 01:18:27
マニュアル読まない奴は多いんだね
■ このスレッドは過去ログ倉庫に格納されています