1 名前:シェルスクリプトライター mailto:sage [2011/12/10(土) 20:06:40.38 ] シェルスクリプトの総合スレです。 スクリプトのお勉強・自慢・腕試しなどにどうぞ。 □お約束 ・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。 Linuxユーザは/bin/shの正体がbashなので特に注意。 FreeBSDユーザは/bin/shの正体がashなので注意。 v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。 src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/ heirloom.sourceforge.net/sh.html ・csh/tcshのシェルスクリプトは推奨されません。 (理由は「csh-whynot」でググれ) ・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。 manや参考リンクを見ましょう。 aproposないしはman -kでそれらしい単語による簡単な検索もできます。 ・シェルスクリプトのことをシェルってゆーな ・シェルで使えるワイルドカード等は正規表現ではありません。 正規表現の話題はスレ違い(正規表現スレへ) □初心者へのアドバイス: ・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも RubyやPerlの方が適した仕事には素直にそちらを使いましょう。 ・知らないコマンドが出てきたらmanを引きましょう。 ・思い通りに動かないときは、まずは sh -x でトレースしましょう。 前スレ シェルスクリプト総合 その18 hibari.2ch.net/test/read.cgi/unix/1308195527/ 次スレは >>970 で。
828 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/07(月) 19:19:08.78 ] 対話方式にならないようにシェルスクリプト自信がroot権限で実行されるようにするスクリプトって作れますか?
829 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/07(月) 21:03:44.73 ] >>828 対話的コマンドでもexpectでなんとかなる
830 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/07(月) 21:11:42.22 ] >>829 そういう意味じゃなくて、シェルスクリプト中で su -c hoge とかしないで root権限の動作をさせたいという質問かとエスパー。
831 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/07(月) 21:16:30.15 ] 基本的にsuidはシェルスクリプトでは許可されてないからねえ。 昔あったsuidperlみたいなののbash版を探してみたけどないみたいだし。 sudersに対象となるスクリプトに対してNOPASSWDを設定するぐらいしか思いつかないや。
832 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/08(火) 02:00:49.38 ] >>828 できます コマンドラインを実行するだけのプログラムを作って setuidするば
833 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/08(火) 07:52:21.31 ] >>832 >>831
834 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/09(水) 13:22:49.97 ] forum.xda-developers.com/showthread.php?t=540483 ここに書いてあるシェルスクリプトを動かしてみたんですが、 Syntax error: "do" unexpectedと返されてしまいます ヒントだけでもいいんで教えてください。
835 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/09(水) 13:28:11.27 ] -x 付けて実行してどこでエラーか見てみたら bash -x secrets.sh
836 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/09(水) 13:29:47.52 ] >>835 わからないなら黙ってろ
837 名前:835 mailto:sage [2012/05/09(水) 13:30:45.77 ] あ、スレ間違えてたorz
838 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/09(水) 15:17:41.55 ] なぜかしら、回答としては合ってる気がするぞw
839 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/10(木) 06:54:48.81 ] コピペの際に文の末尾に\rが入っちゃってるとか。
840 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/14(月) 22:36:21.02 ] alias cd=chdir function chdir { if [ -r "$1" -a -d "$1" -o "$1" = "" ] ; then local i for i in 8 7 6 5 4 3 2 1 0 ; do dirstack[$i+1]=${dirstack[$i]} done dirstack[0]=`pwd` \cd $1 fi pwd } function ds { echo "p:"`pwd` local i for i in 0 1 2 3 4 5 6 7 8 9 ; do echo "$i:${dirstack[$i]}" done } bash用のをcsh(tcshですが)に書き換えてもらえないでしょうか。
841 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/14(月) 22:36:59.98 ] function bd { dirstack[10]=`pwd` \cd ${dirstack[0]} local i for i in 0 1 2 3 4 5 6 7 8 9 ; do dirstack[$i]=${dirstack[$i+1]} done pwd } function nd { dirstack[10]=`pwd` \cd ${dirstack[9]} local i for i in 8 7 6 5 4 3 2 1 0 ; do dirstack[$i+1]=${dirstack[$i]} done dirstack[0]=${dirstack[10]} pwd }
842 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/15(火) 09:15:03.98 ] pushd じゃダメなん?
843 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/15(火) 16:36:43.46 ] >>842 体に馴染んでるんで…すいません
844 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 16:34:35.79 ] もっとマシな方法ありますか?考えても、これくらいしか思いつかない。 デフォルトのBourne Shellではチルダ展開がないようなので、posix shellにて チルダ展開が必要な場合がある、ファイル名に空白等を含んだものが、パラメータに入っているとして、 file_name="~/src/te st" echo "${file_name}をチルダ展開しlsします。\n" ls -l "$( eval echo -n ${file_name} )"
845 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 16:40:45.81 ] lsに限らず、それ以外でも扱える、方法が知りたいです。
846 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 17:10:41.70 ] >>844 例が悪い。その1番下の行の ls -l "$( eval echo -n ${file_name} )" だって、複数の空白が空白1個にまとめられちゃうし、 $ < > 等の記号が含まれると ${file_name} (クォートなし)の展開と evalの展開で大変なことになるぞ。
847 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 17:30:39.54 ] >>846 確かに、例は悪いだろうな。大変なことになる。 でも考えても、これくらいしか思いつかなかったので、 いい加減にして、聞いた方が早いかと書き込んだんだよ。
848 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 17:34:06.75 ] シェル変数内にチルダが入っている時、チルダ展開だけやって その他の空白とか * $ < > とかの解釈はさせないって方法がないんだよな。 sedでチルダを $HOME に書き換えろ。
849 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 17:46:31.95 ] >>844 file_name="~/src/te st * $ < >" ls -l "${file_name/\~/$HOME}"
850 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 18:49:13.65 ] >>846 , >>848 , >>849 あああ!ありがとう。 ls -l "$( echo -n "${file_name}" | sed s#^~#$HOME# )"
851 名前:844 mailto:sage [2012/05/16(水) 21:00:34.05 ] しばらく考えてこうしました。 ls -l "$( [ "${file_name%%/*}" = "~" ] && echo "$HOME/${file_name#~/}" || echo "${file_name}" )" if [ "${file_name%%/*}" = "~" ] then ls -l "$HOME/${file_name#~/}" else ls -l "${file_name}" fi
852 名前:名無しさん@お腹いっぱい。 [2012/05/18(金) 05:23:42.76 ] v7shについて色々調べてるのですがどうしても関数を使用しようとすると test.sh: syntax error at line 2: `(' unexpected とエラーが出てきて使用できません。空白、頭にfunctionを付ける等いろいろ試してみましたがやはり変わらず・・・ UNIX version 7の頃のshには関数がないということでしょうか?
853 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 05:27:04.29 ] sage忘れました。申し訳ないです。
854 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 06:51:13.40 ] >>852 シェル関数はないよ。 代用として、シェル関数にしたい内容をシェル変数に入れて、その変数を実行する。 func='ls -l' $func で ls -l が実行される。引数を渡したい時は工夫して。
855 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 07:00:59.45 ] >>852 あんまり役に立たないかも知れないですが、無いと思います。 参考までに 1. Bourne Shell Tutorial www.grymoire.com/Unix/Sh.html The original version of the Bourne shell didn't have functions. If you wanted to perform an operation more than once, you either had to duplicate the code, or create a new shell script. 2. Linux におけるシェルの進化 www.ibm.com/developerworks/jp/linux/library/l-linux-shells/?cmp=dw&cpb=dwlin&ct=dwrss&cr=dwrss&ccy=jp&csr=012012 ただし、関数を定義する機能は欠けていました。 3. 知っている限りでは、ここが一番情報が多い traditional Bourne shell family / history and development www.in-ulm.de/~mascheck/bourne/ The Variants A summary of the most important changes ? Version 7 (1979) control structures, cmd substitution, () and {}, arbitrary variable names, trap, eval, special parameter substitutions, case ? System III (1981) #, [!...], colon parameter substitution, set -- ? SVR1 (1983) shift n ? SVR2 (1984) functions, built-ins: unset echo type, redirection for builtins 4. 3の下の方のSource codeにある、Nikola Vladov のマニュアルで、 man v7sh BUGS Coexists with but doesn't understand shell functions. 5. FreeBSD Portsはよく分かりませんが、 v7sh FreeBSD www.freebsdsoftware.org/shells/v7sh.html functions aren't supported and command line input is not 8 bit clean
856 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 15:41:41.74 ] >>854 >>855 ありがとうございます!やっぱりなかったんですね case文で;;を使用してもcase文抜けられないのも仕様なのかなぁ マニュアル読んだら使用できそうではあったんですけども・・・一応使用したテストスクリプト上げておきます。 #!/usr/local/bin/v7sh case $1 in a) echo "A!!" ;; b) echo "B!!" ;; c|d) echo "C or D" ;; [e-h]) echo "E kara H" ;; *) echo "NANIKORE?" ;; esac で結果が以下のようになりました。 $ test.sh a A!! NANIKORE?
857 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 16:34:52.98 ] 仕様じゃね? ソースあるんだから読んで解析してくれ 読みにくいってレベルじゃないけど
858 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 20:07:10.23 ] >>856 なんででしょうね? そのままコピペしてv7shで試しましたが、こちらでは期待通りの動作でした。 $ ./v7case.sh a A!! $
859 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 22:31:03.13 ] >>858 謎ですね・・・v7shなんて過去のものですから大差があるとは考えにくいですし 通常のコマンド待ち状態で ;; を打つとエラーが出ますから case内でしか特殊な意味を持たないと思われるんですけどね・・・
860 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/24(木) 17:44:12.51 ] msysgit(windows版git)付属のbashでログイン時のディレクトリをホーム以外にしたいんだけど、どうしたらいい? 例えば、$HOME/work/hogeでいつも作業するのでbash起動時にそこにいて欲しい。 $HOMEを書きかえると他にも影響があり過ぎるので別の方法教えてください。 適切なスレが見つからなかったので、誘導して。
861 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/24(木) 18:49:28.23 ] etc/profileの最後にcd ~/work/hoge?
862 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/24(木) 20:59:36.08 ] そんな単純なことでよかったのか... 恥ずかしいー
863 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/24(木) 21:28:32.29 ] $HOME/.bash_profileの方が良いんじゃ?
864 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/25(金) 02:08:36.57 ] かなり遅れましたが>>834 です -xをつけて実行してみたところ、 # bash -x secrets.sh + echo -n : Invalid argument: apks.txt + echo -n : Invalid argument: output.txt secrets.sh: line 5: syntax error near unexpected toke' `do 'ecrets.sh: line 5: `do 以下のようになりました。