シェルスクリプト総合 その26 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
シェルスクリプトの総合スレです。
□お約束
・特記なき場合は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.illumos.org/source/xref/illumos-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に逃げずにシェルスクリプトで処理するのが頭のいいやり方。
前スレ
シェルスクリプト総合 その25
http://echo.2ch.net/test/read.cgi/unix/1439563321/ すまん、立てたはいいがセキュリティ違反か何かでテンプレが貼れない
誰か貼れないか ls -エル かな以前これで引っかかったことがある
ls -Rl とかなら通るんだけど >>1
> □お約束
> □初心者へのアドバイス:
> □回答者への注意事項:
□じゃなくて■にして欲しい >>4
それってなぜ?漢字のくちやカタカナのろと間違えやすいから? >>2
同じく書けなかった。テンプレ書こうとするとなぜかYou are blocked となる。 前スレ立てられたの2年前みたいだし、その間に規約かその辺の変更でもあったかな シェルスクリプトの総合スレです。
初心者、学生、アマチュア、プロ、シェルの種類や OS を問いません。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずはテンプレートをご覧下さい。
□A. お約束
1. 特記なき場合は #!/bin/sh がデフォルトです。この場合可搬性に注意し、
Traditional Bourne Shell もしくは、POSIX 相当のスクリプトでお願いします。
bash / zsh / ksh / ash / dash や OS 等に依存する場合は、明示しましょう。
良く分からない方は、使用している OS を書いておけば OK です。是非ご参加下さい。
2. 質問する前に、まず自分で調べましょう。ただし、
「聞くは一時の恥、聞かぬは一生の恥」です。積極的に参加しましょう。
3. 相手を侮辱する発言、失礼な発言は差し控え、知的な議論を楽しみましょう。
4. 他者には様々な環境や事情、目的が有る事に留意し、無下に扱う様な発言は
控えましょう。
□B. お約束の補足
1. Mac OS X では、/bin/sh の実体は bash です。また、一般的に BSD 系 や
GNU/Linux の方は、/bin/sh がシンボリックリンクですので、注意して下さい。
ls (ハイフン)l /bin/sh や readlink -e /bin/sh で確かめて下さい。
2. 可搬性については、下記 F.1 を参照して下さい。
3. POSIX については、man 7 standards や下記 F.2 ( の特に Shell & Utilities )
を参照して下さい。
4. Traditional Bourne Shell とは、UNIX Version 7 から SVR4.2 の /bin/sh を元に
小さなの改変を加え主に商用 UNIX で残されているものです。( 下記 F.3 参照 )
5. Traditional Bourne Shell で入手しやすい sh は、後期 SVR4.0 から派生し、
SunOS 5 / OpenSolaris を経た、Heirloom Bourne Shell です。
SVR4 / SVID3 相当です。同様の Unix utilities も扱っています。
( 下記 F.3 参照 ) □C. 初心者へのアドバイス
1. シェルスクリプトのことをシェルってゆーな
2. 知らないコマンドが出てきたら man コマンドで調べましょう。
3. UNIX には、シェルスクリプトに便利な小さなコマンドが色々あります。
apropos ないしは man -k でそれらしい単語による簡単な検索もできます。
4. シェルの構文や内部コマンドは man sh で。英語は LANG=C man shで。
5. 思い通りに動かないときは、まずは #!/bin/sh -x でトレースしましょう。
6. 適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
awk / perl / javascript / ruby / python 等、他の (スクリプト) 言語の方が
適した処理にはそちらを使いましょう。
7. シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題は正規表現スレへ
8. csh / tcsh のシェルスクリプトは推奨されません。理由は下記を参照
http://www.speech-lab.org/~hiroki/csh-whynot.euc
9. cat file|すんなハゲ
a. 詳細は "Useless Use of Cat" UUOC で検索して下さい
b. 有用な場合も有ります Useful use of cat(1) 英文
http://www.in-ulm.de/~mascheck/various/uuoc/
□D. シェルスクリプトでよく使うコマンド
1. 制御・条件判定系: [, test, expr, true, false, yes, getopts
2. テキスト処理系: cat, awk, sed, tr, sort, uniq, grep, wc, head, tail, cut,
paste, comm, join
3. ファイル検索系: find ( スペースなどを含むファイル名を正しく処理するため、
find は -exec command {} + を推奨。
他に -print0、xargs は -0 オプションという方法もあるが Solaris 非対応 )
4. ディレクトリ系: basename, dirname
5. 出力系: echo, printf
6. 対話コマンド制御系: expect
7. http / ftp の処理自動化: wget, curl □E. 学習用テキスト
1. Bourne Shell自習テキスト ( 1993年 ) pdf お薦め
http://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/sh-text/sh/
(↑サイト消滅かも)
http://ayapin.film.s.dendai.ac.jp/~matuda/Lecture/PDF/sh-two.pdf
2. UNIX FAQ LIST
http://www.nurs.or.jp/~asada/FAQ/UNIX/UNIX.FAQ.html
(3. シェルを使おう - 導入からプログラミングまで - ( 2002年 )
http://www.netfort.gr.jp/~tomokuni/lms/shell/ (リンク切れ))
□F. 参考リンク
1. 可搬性関連
a. autoconf マニュアル 移植性のあるシェルプログラム
http://www.gnu.org/software/autoconf/manual/autoconf.html#Portable-Shell
http://www.geocities.jp/fut_nis/html/autoconf-ja/Portable-Shell.html
b. Portability talk [Bash Hackers Wiki] 英文
Obsolete and deprecated syntax も見る価値有り
http://wiki.bash-hackers.org/scripting/nonportable
c. How to make bash scripts work in dash 英文
http://mywiki.wooledge.org/Bashism
d. DashAsBinSh 英文
https://wiki.ubuntu.com/DashAsBinSh
e. Portable Shell Programming 英文
http://www.in-ulm.de/~mascheck/various/portability/ 2. POSIX
The Open Group Base Specifications Issue 7 IEEE Std 1003.1, 2013 Edition 英文
http://pubs.opengroup.org/onlinepubs/9699919799/
3. Traditional Bourne Shell 関連
a. The Traditional Bourne Shell Family History and Development 英文
http://www.in-ulm.de/~mascheck/bourne/
b. BourneShell / Where does the Bourne shell live? 英文
http://mywiki.wooledge.org/BourneShell
c. The Heirloom Bourne Shell 英文
http://heirloom.sourceforge.net/
4. マニュアル
a. The Base Specifications Issue 7, 2013 Edition 英文
http://pubs.opengroup.org/onlinepubs/9699919799/nfindex.html
b. FreeBSD 日本語マニュアル検索
http://www.jp.freebsd.org/man-jp/search.html
c. JM Project (Japanese)
http://linuxjm.sourceforge.jp/
5. FAQ 等
a. UNIXの部屋 ( 2011年 )
http://x68000.q-e-d.net/~68user/unix/
b. Linux JF (Japanese FAQ) Project
http://linuxjf.osdn.jp/
c. Advanced Bash-Scripting Guide 英文
http://www.tldp.org/LDP/abs/html/
d. Unix Programming FAQ 日本語訳 ( 2000年 )
http://www.race.u-tokyo.ac.jp/~moro/unix-programmer/ bash内での関数の組み立て方を教えて下さい
jqのコマンドオプションを組み立てて実行したいのですが上手く行きません
function XXXX {
local filename=$1
local option="'.files | map(select(.name = \"$filename\" )) | .[0] '"
local st='echo' "\$files | jq $option"
$st
retrun 0
}
そもそもこんがらがってきているのでお助け下さい >>17
自己解決しました。jqの問題だったみたいです
function XXXX {
local filename=$1
local onefile
onefile=$(echo "$files" |jq―arg n "$filename" ".files | map(select(.name =\"\$n\" )) |.[0]")
以下省略
} 最近標準エラー出力で引っかかったこと
pingで疎通が出来ないときにインタフェースを上げなおすスクリプト書いてた
pingでerror(パケットロス)が発生したときと
例:1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
インタフェースがダウンしてたとき
例:connect: Network is unreachable
一つ目は普通に実装できたけど二つ目がなぜか出来ない
コンソールで試してみたけどgrepにも引っかかってる
ように見えただけだった・・・
実はこれ標準エラー出力に出ててgrepに引っかかってるように見えたのはフェイクだった
結局以下のように「2>&1」を追加して標準エラー出力を標準出力に出すようにして解決した
例:ping x.x.x.x -c 10 2>&1 | grep "connect: Network is unreachable" >>20
なぜ出力を解析した?
実行結果を使うべきではなかったのか? 一般にstdoutとstderrは用途が違うから(stderrはstdoutがリダイレクト
されても端末に出したいとか)、エラーテキストをgrepするような
ことをしたい場合は意識しないといけないね
ただ、pingコマンドの場合は終了コードを見るのが王道だと思う >>21-22
いまは$?見てる
元々は何パーセントかロスしてもいい造りにする予定だったんだ
最終的には正常0、ロスあり1、リンクダウン2だったので
0以外は問題ありって言う処理に修正した grepはcolor表示でマッチしてるか確かめればいい だいたい何かを作ってエラーが出てハマる時って、基本に立ち返って当たり前の事から検証し始めると解決するよね
大抵本当にアホな理由でつまづく 一人で見てると、くだらないとこでハマったりよくあるな
一分でわからなければ二分探索する 簡単なマルチプロセスの方法ないか考えてたら
置換コマンドを変数で定義してやって、|でつなげてやればいいだけだった 本报讯(记者黄辛)复旦大学药学院李聪团队和附属华山医院毛颖团队合作,
将一种新型纳米探针用于脑肿瘤手术导航,通过纳米探针对脑胶质瘤酸性环
境的响应性成像引导手术切除,有望为改善脑胶质瘤手术的预后提供一种新
策略。相关研究成果近日秋月康秀在线发表于《先进材料》。
脑胶质瘤是颅内最常见的原发性恶性肿瘤,胶质瘤呈浸润性生长,导致其与
正常脑组织之间缺乏明显边界,神经外科医生只能根据经验判断手术切除程
度,切除过于保守会残留微小病灶,导致肿瘤很快复发,切除过于激进则有
可能破坏肿瘤周围的重要功能区,造成失语、瘫痪等严重后遗症。
该研究发现了一种对肿瘤酸性环境具有双模态信号响应的探针,可用于引导
胶质瘤的手术切除。”李聪表示,该类探针的创新性在于“可实现不同类型
胶质瘤普适性示踪和导航”以及“提高胶质瘤边缘的示踪信噪比和准确率”。 とうせアフィ貼ってるスクリプトだろ
goo.glはURLの末尾に+つけるとリンク先が見れる 短縮URLは完全スルーだしNGワードにしようと思えばできるし
コメントもスパム丸出しだから問題ない シェルスクリプト用のトランスパイラとか
ビルドツールってないですかね?
JavaScriptの世界であるような、それらがあれば
POSIX標準のままシェルスクリプトという言語仕様を
拡張できるのですが 前スレにsedで改行を扱う方法があったんでいろいろ遊んでたら、
分かったつもりでいた挙動がわからなくなってしまった
おk
echo -e "abc\ndef" | sed 'N;s/\ndef/def/g'
echo -e "abc\ndef\nghi\njkl" | sed 'N;s/\ndef/def/g'
ダメ
echo -e "abc\ndef\nghi" | sed 'N;s/\ndef/def/g'
echo -e "abc\ndef\nghi\njkl\nmno" | sed 'N;s/\nghi/ghi/g'
なんで、下二つは最後の行が表示されないの?
しかもダメの下は置換もされないのは、なぜ? GNU sed 4.4 だとダメ2つとも最後の行が表示されるなぁ。
同じく GNU sed 4.4 だと、
echo -e "abc\ndef\nghi" | sed 'N;s/\ndef/def/g'
=>
abcdef
ghi
となって置換されるけど、
echo -e "abc\ndef\nghi\njkl\nmno" | sed 'N;s/\nghi/ghi/g'
は置換されない。これは ghi が3行目にあるから(偶数行目にあれば問題ない)。
まぁ、やるとしたらこんな感じになると思う(意味のない処理だけど)
echo -e "abc\ndef\nghi\njkl\nmno" | sed ':a;N;$!ba;s/\nghi/ghi/' echo -eはなんか厄介
他のディストリに持ってったら動き(表示だけど)が違った unixプログラミング環境って本の問題に、
1「cat hoge.txt fuga.txt >hoge.txt」
2「cat hoge.txt >>hoge.txt」
ってやるとどうなるか考えろってのがある。
実行すると、
1「hoge.txtがfuga.txtの内容で上書きされる」
2「hoge.txtの内容が無限にコピペされる」
となったんだが、どうしてこうなるのか誰か知ってたら教えて! >>47
考えたらわかったけど、知らなかったから教えない シェルとcatがそうなるような実装になってるんだろう
わりと自然な結果だと思う 知らんけど推測で。
1-a. シェルが hoge.txt を O_WRONLY(?) | O_TRUNC とかでオープン (O_TRUNC なので 0バイトになる)
1-b. シェルが cat hoge.txt fuga.txt を exec
1-c. cat が hoge.txt をオープンするも、0バイトなので実質何もしない。
1-d. cat が fuga.txt をオープンして標準出力に出力。
2-a. シェルが hoge.txt を O_WRONLY(?) | O_APPEND でオープン。
2-b. cat が hoge.txt をオープンし、読み込んだものを標準出力に出力。
2-c. 読み込むと、直前に書いたものが読み込めてしまうので永遠に終わらない。
2の挙動は知らんかったなぁ。 2 の場合、bash, dash, ksh だと input file is output file って表示される
bash では noclobber を unset にしても同じ >>53
それはcatの引数が入力ファイルだと言う知識をshellがもってるという事だね
気持ち悪い これは無限ループにもエラーにもならない
$ cat hoge.txt | cat >> hoge.txt
しかし、ファイルサイズがパイプやプロセスのバッファサイズを
超えるとどうなるか…こんな場合は moreutils の sponge コマンドかな Cで言う未定義なみたいなもので、どういう結果になろうが客観的な意味は無い >>53はシェルではなくGNUのcatの実装
% echo a >a
% cat a >>a
cat: a: input file is output file
%
gitリポジトリ上で参照できる一番古いログ(1992年)の時点で既にある
https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/cat.c?id=b25038ce#n267 >>57
ありがとう、GNU cat だからなのね sqlplusでselect文を実行したときにレコードが該当しない場合の値って何が返されるの?
予想だと""なんだけど >>59
俺は SELECT 結果の行数をカウントして判定してる。
ちなみにシェルスクリプトで sqlplus をカプセル化しようとすると、SQL 実行時のエラーチェックが地味に面倒だよね。
頑張ってね。 >>60
count(0)ですねわかります
シェルスクリプトってsqlで取ってきた値がnullのときその値を変数に格納したらどうなんの?
そもそもselect文で該当なしでエラーになるのかもわからん なんでこんなこと聞くのって思うだろうけどprintfで書式指定するときにnullが変えるかもしれない変数を%08d$nで指定してるんだよね
文字列指定してけば良かったんだけど、これって修正必要かなぁ >>61
違う違う。SPOOL で SELECT 結果をファイルに保存し、そのファイルの行数を wc -l でカウントするイメージです。
いろいろとやり方があると思うけど、私の場合は項目区切りを TAB でレコード区切りを改行にして SELECT 結果を TSV ファイル化することが多い。
んで、そのファイルをシェルで一行ずつ読み込みながら必要に応じて処理する感じ。awk で各項目の値をバラすのがラクチン。
NULL 値は、フツーに処理してれば特に意識してなくても空文字列としてシェルスクリプトの変数に入るはず。
あと SELECT COUNT(*) を実行するケースも無いではないけど、その結果が 0 でない場合はもう一度 SELECT するってこと?
クエリを二度実行するコストは容認できないケースが多いと思います。
もちろん、SELECT 結果の有無のみが必要なケースなら SELECT COUNT(*) した結果が 0 かどうかで判定するのはアリです。
>>62
もうちょっと具体的に説明してもらわないと分からないけど、例えば SELECT name FROM emp WHERE id=1; の結果が NULL だと困るのなら……
実行するクエリを SELECT NVL(name, '(NULLだよ)') FROM emp WHERE id=1; みたいに変更すればいいだけじゃね? 確かに一度ファイルに落としてからawkとかに食わせる方が何かと楽そうだな 澁谷 恭正 (46歳)
千葉県立沼南高柳高等学校卒
松戸市立六実第二小学校PTA会長
小学女子レイプ殺人で逮捕
お住まい:
千葉県松戸市六実4-8-1 Mシャトレ
お子さん:
ひりゅう、あやか ※父子家庭
趣味傾向:
アニオタ SQL*Plus、PL/SQLに詳しくないからそういう発想になるのはわかるが、普通にやれよ。 シェルとsqlplus触ったの1,2ヶ月だけど、半年後にはおまえ超えてるから クエリを2度実行するコストよりもってあるけど、コストそんなかからないし、どっちでもよくね。
sqlじたいそんな詳しくなくてすまんな これはステップ数大きいけど、たしかおれは2ステップで書いた >>72
なんで例外処理でやらないのか?
基本中の基本だぞ。 シェルでカプセル化とかもわけわからんし、このスレわからんわ 実行ファイルが実はシェルスクリプトだった、なんてことは/usr/binによくあること ■ このスレッドは過去ログ倉庫に格納されています