シェルスクリプト総合 その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/ X 使ってないから分からんが、Windows でエクスプローラからコマンドプロンプトにドラッグ&ドロップするとファイルパスが入力されるのと同じ機能かな。 意外と知らない人もいるみたいだけど、便利だよね。 Windows でも確認できた。へー,結構便利だな。 どうでもいいけどそれずっとsakuraエディタ使ってやってたわ エディタ上にファイルペーストすると絶対パスに変換される DEの機能じゃないの ファイルマネージャー使わないが Terminology って何がすごいの? 画像の表示なら xterm ですら可能なのに。 lsとかした後ターミナル内でのD&Dとかの変態操作 動画再生と動画壁紙の無駄機能 すごくはない ターミナル内で D&D できんのか。そりゃすげえ。 unix プログラミング環境という本の問題でpickというプログラムを作ったんだ。 引数ごとに出力するかを対話して、"y"が押されたものだけ出力するという単純なもの。 --- $ pick a b a? y a b? n $ --- 問題ではさらに、「引数が無かった時は標準入力を読みに行くようにせよ」と続く。 まあ、パイプで挟まれたりしても問題なく使えるようにしろってことなんだと思う。 で、以下の様に書いて、問題なく動いたんだけど、 あまりシェル書いたことないもので・・・変な書き方してないかとかコメント頼みます。 --- exec 10<&0 11>&1 0<&2 1>&2 input='echo "$@"' if [ $# -eq 0 ] ; then input='cat <&10' fi for i in `eval $input` do echo -n "$i ? " read response case $response in y*) echo $i >&11 ;; esac done --- >>289 その本知らないけど、標準入力を読み切ったあとをキー入力とするより read response < /dev/tty でキー入力する方が一般的じゃないかな >>291 実は、vmware上のlinuxにテラターム使ってテストしてたんだけど、 (unixと書いてあるのにスマン) その時の端末のデバイスファイル?とやらが/dev/pts/0だったのよ。 `tty`でもパイプ使ってると「あいまいです」みたいに怒られちゃって、 苦し紛れに&2を使ってしまった。。 接続端末のデバイスファイルをいつでも取得できる方法ってあるのかな? あ、あと今さっき教えてもらった read response < /dev/tty ↑が、上手くいった!ありがと〜 unixだとreadコマンドはリダイレクションができなかったらしいが、 linuxだと出来るのか。。。 1. find . -name aaa -o -name bbb はうまくいくけど 2. find . -name aaa -o -name bbb -print では aaa が引っかからなくて、 3. find . \( -name aaa -o -name bbb \) -print だと OK な理由がいまいちわかりません。括弧なしだと 4. find . -name aaa -o \( -name bbb -print \) と解釈されてしまうからってのはわかりますが、 「アクション指定なしの場合 -print の挙動となる」 「exp1 -o exp2 で exp1 が偽なら exp2 を実行しない」 であるならば、1 が表示されて、2・4 の aaa が表示されないのはなぜでしょう。 ちなみに、GNU find(1) には下記。 If the expression contains no actions other than -prune, -print is performed on all files for which the expression is true. FreeBSD の find(1) は下記でした。 If none of -exec, -ls, -print0, or -ok is specified, the given expression shall be effectively replaced by ( given expression ) -print. と書いていて思いましたが、括弧等や -o に関係なく、引数 expression のどこかに アクションが 1つでも記述されていれば、-print を補完しない、ってことですかね。 > 括弧等や -o に関係なく、引数 expression のどこかに > アクションが 1つでも記述されていれば、-print を補完しない、ってことですかね。 ということのようでした。 https://svnweb.freebsd.org/base/head/usr.bin/find/function.c?revision=314436& ;view=markup#l1344 -print とかが見つかると isoutput=1 とする。 https://svnweb.freebsd.org/base/head/usr.bin/find/find.c?revision=314436& ;view=markup#l113 !isoutput の場合のみ、-print を補完する。 expression のツリー構造をたどって、アクションがない expression が 見つかったら全部 -print を補完する、としていたらよかった気がしますが、 いまさらどうしようもないですね。 $ bc <<< '6*7' 42 とかの`<<<` ってなんという名称ですか? ヒアドキュメンとだとずっと思っていたのですが,その仕様を調べようとしたらヒアドキュメントというのは $ cat << . > ~/foo.txt a b c . の << . から . を指すようなのでした。 >>297 ありがとうございます! お礼が遅くなり申し訳無いです。 あるマシン環境を仮想マシンとかでバックアップしておいて 1つのマシン上であるサーバを構築して、 historyからその構築したコマンド群を全部シェルスクリプトに コピペして、そのシェルスクリプトを サーバ構築前のマシン上で実行したら全く同じサーバが一瞬で構築できるの? 冪等性が保証されてるスクリプトなら同じサーバーができる ネットワーク経由のインストールとかしてて サーバの状態により変わりそう サーバーじゃないけど仮想マシンで似たような事してる ヒストリーからってより自分でメモしといたコマンド群だけど けっこう省力化出来てる あとスクリプト書いてから時間が経過するとソフトウェアの ダウンロード元のURLが変わったりしてエラーが出ることは多々ある 結局リプレイしたいときにはアプリやOSのバージョンが微妙に上がってて、 手順を修正しながらやらなきゃダメってのはありがちだな。 変数やコマンド文字列の展開と ワイルドカード/正規表現の展開って原理が違うの? >>306 言ってることが曖昧だが,「グロブ」と「正規表現」は違うよ 原理が違うかどうかは知らんが,少なくとも挙動は別物 例えばアスタリスクはグロブだとワイルドカードとして,正規表現だとクリーネ閉包としての役割を果す グロブ(含ワイルドカード)と正規表現の違いを聞いてるのではないでしょう みなさんコマンドの頭にバックスラッシュって付けてます? 私は安全を期して付けているのですが そうしているシェルスクリプトが以外に少ないので 気にしなくてもいいんですかね alias cp='rm -rf' cp a --> rm -rf a \cp a --> cp a cshはデフォルトだと必ず.cshrc読んじゃうからねぇ >>306 翻訳するとこういう感じだと想像 変数の展開: variable expansion ( e.g. ${var} ) コマンド文字列の展開: command substitusion ( e.g. $(command) ) ワイルドカードの展開: filename expansion ( e.g. *.sh ) 正規表現の展開: ??? 正規表現の展開って何? find -regexとかのこと言ってるの? あと原理って? 同じか違うか知りたい理由は何? 人に伝わるように質問しないと誰も分からないぞ >>321 前提というか、 >>313 はそういう環境なんだなと深読みしただけ >>315 はcshじゃないな。 むかしのcshで痛い目にあってなますを吹いてるとか? >>322 深読みが過ぎるのでは Bシェル系使ってて心配しすぎてるだけという可能性もある >>313 を見て思ったのが シェバンの書き方。 #!/bin/sh - と書けと駱駝にはあったが 存外そうしている Shell Script がない まあ余程のことがない限り sh がオプションを勘違いするなんてないが #!/bin/sh - set -x set -u ... set +u set +x 新しい関数として ls () { \ls --width=`\echo $COLUMN` } という関数を作って,ls のエイリアスとして動作させたいのですが, コマンドラインで $ ls と入力すると無限ループに陥ります。 多分というか確実に関数 ls が自分自身を呼び出している為に生じる現象だと思います。 これを回避し,ls という関数を安全に作製するにはどうすればいいでしょうか。 常用しているシェル bash です。 bash 独自の拡張でそのような(関数の再帰を防ぐ)機能があれば教えて下さい。 command ls --width=$(echo ${COLUMN:-50}); とかでいいんじゃない >>332 様、>>333 様、ありがとうございます。 どちらの方法でも上手く行きました。身勝手ながら >>333 様の方法を採ることにしました。 蛇足気味ですが、最終的に以下のような関数にしました。良かったら添削してください。 POSIX とかは考えてないです。 function ls () { local _opt="--ignore-backups --color=always --format=across --group-directories-first --indicator-style=classify --literal --sort=time --width=`\echo $COLUMNS`" command ls $_opt } s:/`\\echo $COLUMNS`/$(\\echo ${COLUMNS})/ Better? function ls () { local _opt="--ignore-backups --color=always --format=across --group-directories-first --indicator-style=classify --literal --sort=time --width=$(\command echo ${COLUMNS})" \command -p ls $_opt $@ } lsを常に特定のオプション付けて実行したいのならLS_OPTIONS使えばいいと思う それからfunction name ()はfunction nameかname () のどちらかにすべき name()の方が汎用性高い >>337 ありがとうございます! LS_OPTIONS は知りませんでした。MANOPT や LESS みたな感じなんですかね。 函数は POSIX に合わせて ls () にしようと思ったんですが,ちょっと個人的に気持ち悪くて,どうしても function が取っ払えませんでした……。 シェルの解釈を標準出力に印刷するコマンドってある/作れますか? グロブやエイリアスがどう解釈/引き渡されるのかを知りたいです。 $ showraw 'ls */*' ls a/a a/b a/c b/a c/a c/b みたいな。 検索も一通りしたのですが見付からないです。 シェルによってシェルそれ自身の機能を調べるのは無理なんですかね。 $ showraw 'ls */*' ls -F -A a/a a/b a/c b/a c/a c/b エイリアスも解釈されるのでこんなかんじですね。 コマンドの方はtype ls 引数の方はecho */* で良くね 取り敢えずshとbashで確認 $ ls */* と入力したところで ESC \C-e をタイプするとエイリアスが展開され \C-x* をタイプするとワイルトカードが展開される >>340 $ set -x $ ls */* >/dev/null >>343 -- >>345 ありがとうございます。しかしできればエイリアスごと展開したいのです。 >>346 おわ!まさにこんな感じです。多分コマンドプロンプト関連の命令群も一緒に出力されますが,これはまあ awk か何かで頑張って切り取ります。一応 zsh,bash,dash で確認できました。 >>330 set -u 便利ですね ~/.bashrcに書こうかしら とくに弊害ないですよね? すいません。わかるかたいたら教えてください。 基本的にカンマ区切りの行なのですが、1列目が""で囲まれ、"aaa,bbb,ccc"のように なることがあります。 1列目のみに発生します。 この1列目のケースだけ、カンマをスペース等に置換したいと思っています。 イメージはこうです。 "aaa,bbb,ccc",AAAA,BBBB,CCCC aaa,AAAA,DDDD,EEEE ↓ "aaa bbb ccc",AAAA,BBBB,CCCC aaa,AAAA,DDDD,EEEE 理由はエクセルに取り込むときにずれてしまうためです。 awkで出来た気がするのですが、うまく出来ません。 どなたか心当たりないでしょうか。 Excelならダブルクオートちゃんと扱うはずだよ 勘違いか、変な文字入ってない? テキストをコピーして貼り付ける時にカンマ区切りでバラすように貼り付けると囲んでてても関係なくバラさなかったっけ? もっとうまく書けそうな気がするものの perl -pe 'if (/^"/) { @f = split/"/, $_, 3; $f[1] =~ s/,/ /g; $_ = join "\"", @f }' awkとBEGINで昔出来た記憶があるのですが。上手くいかず。 >>350 あれ、確かにEXCELには想定ではれました、すいませんさっきも同じにようにはったつもりで、ばらされたのですが。 >>353 一行Perlの文法の意味はわかりませんが、確かに出来ました! 区切り文字を"にして配列に取り込んで,を に置換えた後、最初と最後に"を追加する perl -F\" -anle '$F[1] =~ s/,/ /g; $F[1] =~ s/(.+)/\"$1\"/; print @F' awkでは awk 'BEGIN {FS="\""; OFS="\""} {gsub(","," ",$2); print $0}' でいいような、なんか自信ないけど GNU awk の FPAT を使ってこんな感じで gawk -vFPAT='(".+?"|[^,]*)' -vOFS=, '{gsub(/,/," ",$1);print}' data.csv perl -pe 's/^("[^"]*")/$1=~s|,| |gr/e' perl -pe 's/,(?=.*\")/ /g' >>349 #!/bin/sh IFS=\" while read X Y Z ; do if [ "$X" = "" ] ; then echo -n \"$Y\" | sed 's/,/ /g' echo $Z else echo $X fi done sed '/^"[^"]*"/{H;s///;x;s/\n//;s/^\("[^"]*"\).*/\1/;s/,/ /g;G;s/\n//;}' bashで変数展開するときに、名前末尾にハイフン付けるのはどういう意味なんでしょうか? ${abc-} 今まさにそのページ読んでたけど、:いるよな ナシの使い方なんてあったっけか > コロンを省略した場合には設定されているかどうかのみを調べます。 何度か読み返してようやく理解した unsetされてるか空値が入ってるかの違いに対応出来るのか ログイン時に読み込まれる ~/.profile ファイルは,「誰が」読み込んでいるのでしょうか。 普通 sh もしくはその代替シェルかなと思うのですが,実際はどうなのか気になります。 というのも,私が普段使っている Debian GNU/Linux ではデフォルトシェルは bash に指定しているのですが,~/.profile の中に bash っぽい変数 (${HOGE} という書き方) があったので。 あぁ、すまん >>368 へのレスか たしかに${HOGE}記法はたいていのshで使えるね ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる