シェルスクリプトの総合スレです。
□お約束
・特記なき場合はBourne Shell(/bin/sh)もしくはPOSIX準拠の互換シェルがデフォルトです。
bash/zsh/ksh/ash/dash/yash/poshなどの専用機能に依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashまたはdashなので特に注意。
FreeBSDユーザは/bin/shの正体がashなので注意。
・POSIXについてのリンクは https://en.wikipedia.org/wiki/POSIX にまとめられています
最新の仕様はこちらへ http://pubs.opengroup.org/onlinepubs/9699919799/
(左上の「Shell & Utilities」 から参照することができます。)
・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に逃げずにシェルスクリプトで処理するのが頭のいいやり方。
質問に対して問題が間違ってるといちゃもんをつけるのもやめましょう
前スレ シェルスクリプト総合 その26
https://mevius.5ch.net/test/read.cgi/unix/1489979246/
シェルスクリプト総合 その27
■ このスレッドは過去ログ倉庫に格納されています
2018/05/03(木) 17:54:23.25
2018/06/15(金) 21:35:58.85
元々何が気に入らなかったのかイマイチわからない
2018/06/15(金) 22:35:17.99
POSIX的に気に入らない
2018/06/15(金) 23:11:38.57
POSIX POSIXうっせー
2018/06/15(金) 23:13:05.02
2018/06/16(土) 00:18:50.65
findutilsのソース取って来てあのメッセージ出ないようにパッチして使っちゃえよもう
http://git.savannah.gnu.org/cgit/findutils.git/tree/find/exec.c?h=v4.6.0#n354
http://git.savannah.gnu.org/cgit/findutils.git/tree/find/exec.c?h=v4.6.0#n354
2018/06/16(土) 00:33:50.14
>>616
find . -exec sh -c 'trap "exit" pipe; basename {}' \; -o -quit | head
find . -exec sh -c 'trap "exit" pipe; basename {}' \; -o -quit | head
2018/06/16(土) 01:07:40.99
>>638
試してないけど、trapせずにbasenameのあとにexitするだけでだめなん?
試してないけど、trapせずにbasenameのあとにexitするだけでだめなん?
2018/06/16(土) 08:33:03.61
find /etc -exec basename \{\} \; |& head
これでエラーも出ず余計な出力も引っ掛らなかったんだけど
理屈が分からん
|& は標準出力と標準エラー出力両方を通すはずなので
SIGPIPEのエラーが出力されるはずだがgrepしても見当らない
これでエラーも出ず余計な出力も引っ掛らなかったんだけど
理屈が分からん
|& は標準出力と標準エラー出力両方を通すはずなので
SIGPIPEのエラーが出力されるはずだがgrepしても見当らない
2018/06/16(土) 10:03:37.06
find自身がSIGPIPEで終了してんじゃない
実行時間も短くなってるし
実行時間も短くなってるし
2018/06/16(土) 10:39:12.35
Linux なら strace で見ると分かる
$ strace -f bash -c 'find /etc -exec basename \{\} \; |& head'
$ strace -f bash -c 'find /etc -exec basename \{\} \; |& head'
2018/06/16(土) 11:10:29.82
stderrが(標準出力)のパイプになりの、そのパイプが無くなり、find自身がエラーメッセージをそれに書き込もうとしてSIGPIPEを受けるってとこか
find . -exec basename {} \; -o -print | head
としても同じように終わるってとこで
find . -exec basename {} \; -o -print | head
としても同じように終わるってとこで
2018/06/16(土) 12:55:30.00
>>644
ほほう
ほほう
2018/06/16(土) 13:02:42.26
2018/06/16(土) 13:15:44.53
2018/06/16(土) 13:16:47.78
2018/06/16(土) 13:26:10.67
ああ、|& は元々はzshのなのか(?)
macOS Sierra標準のzshでは/でも、>>640のままで特に何も問題なく終わった
macOS Sierra標準のzshでは/でも、>>640のままで特に何も問題なく終わった
2018/06/16(土) 14:10:29.68
>>649
|&はcsh由来。zshはパクっただけ。
|&はcsh由来。zshはパクっただけ。
2018/06/16(土) 17:20:45.43
|&はPOSIXなの?
2018/06/16(土) 17:32:28.45
やかましいわっw、おばかさん
2018/06/16(土) 17:58:54.17
それはPOSIXですか?POSIXじゃないのですか?
2018/06/16(土) 18:00:34.28
ところで俺のPOSIXを見てくれ。こいつをどう思う?
2018/06/16(土) 18:14:03.11
すごく、標準的です
2018/06/16(土) 18:39:24.01
Is it POSIX?
2018/06/16(土) 18:58:44.20
No, it is Apple
2018/06/16(土) 19:58:16.75
まあPOSIXじゃないので質問者の要請は満たしてないよね
俺が提案するとしたらexecは使わず
find . | xargs -I @ basename @ | head
↑これ。
俺が提案するとしたらexecは使わず
find . | xargs -I @ basename @ | head
↑これ。
2018/06/16(土) 20:06:12.48
それじゃあかんだろ。xargsのオプションが足りない
2018/06/16(土) 20:09:55.36
いいのか。すまん
2018/06/16(土) 20:37:42.14
俺がやるなら xargs -I には {} を 指定するがな
@というのは見たことがない 社内規約かなにかかな?
@というのは見たことがない 社内規約かなにかかな?
2018/06/16(土) 20:51:48.06
>>656-657
定冠詞がないよ
定冠詞がないよ
2018/06/16(土) 20:56:44.95
この問題って本質的には、 find は /etc の下の全部のファイル(10以上)を返すが、
head は 10行で打ち切ってしまうという矛盾にある。
そこは目をつぶるって方針なんだから、最初に書いてあったstderrを捨てるって
方法で正しいと思うよ
head は 10行で打ち切ってしまうという矛盾にある。
そこは目をつぶるって方針なんだから、最初に書いてあったstderrを捨てるって
方法で正しいと思うよ
2018/06/16(土) 20:59:20.95
2018/06/16(土) 21:30:02.51
2018/06/16(土) 22:02:52.02
>>662
マジレスアッポー
マジレスアッポー
2018/06/16(土) 23:19:14.74
コマンドの重複を数える(つまり$PATHに登録され実行可能なファイルの重複を列挙する)一番短い方法をってなんでしょう。ただし確実に動作しかつ可搬であることが条件です。
僕が考えたのは
$ echo $PATH | tr ':' '\n' | xargs -I @ find @ \( -type f -a -perm -+x \) -exec basename \{\} \; | sort | uniq -c
です。
僕が考えたのは
$ echo $PATH | tr ':' '\n' | xargs -I @ find @ \( -type f -a -perm -+x \) -exec basename \{\} \; | sort | uniq -c
です。
2018/06/16(土) 23:24:18.70
basenameにしたらファイル名じゃなくなるじゃん
2018/06/16(土) 23:36:17.54
2018/06/17(日) 04:18:06.91
パスの中に空白が入ってる or PATHの中身が多すぎたらおそらくアウト
( IFS=:; find $PATH -type f -a -perm -+x ) | sed 's|.*/||g' | sort | uniq -c
( IFS=:; for i in $PATH; do find "$i" -type f -a -perm -+x; done ) | sed 's|.*/||g' | sort | uniq -c
( IFS=:; find $PATH -type f -a -perm -+x ) | sed 's|.*/||g' | sort | uniq -c
( IFS=:; for i in $PATH; do find "$i" -type f -a -perm -+x; done ) | sed 's|.*/||g' | sort | uniq -c
2018/06/17(日) 08:19:10.40
できればsedでやりたいことなんですが
aaa
<<
bbb
>>
もしくは
aaa
<<bbb>>
というようなファイルがあったとしてaaaの次行から「>>」を含む行までを読み出したいです。
(aaaが存在する行はすでに具体的な数値で判明しています; ここでは42行目とします)
特に二番目の場合には sed -n -e '43,/>>/p'とやると43行目に「>>」があるのに見つけてくれません。
なにか手助けをおねがいします。
aaa
<<
bbb
>>
もしくは
aaa
<<bbb>>
というようなファイルがあったとしてaaaの次行から「>>」を含む行までを読み出したいです。
(aaaが存在する行はすでに具体的な数値で判明しています; ここでは42行目とします)
特に二番目の場合には sed -n -e '43,/>>/p'とやると43行目に「>>」があるのに見つけてくれません。
なにか手助けをおねがいします。
672名無しさん@お腹いっぱい。
2018/06/17(日) 09:24:18.61 >>671
sed -e '42,/>>/!d' -e 42d
sed -e '42,/>>/!d' -e 42d
2018/06/17(日) 12:39:57.71
あれんじ
sed -e '43,$!d;/>>/q'
sed -e '43,$!d;/>>/q'
2018/06/17(日) 14:39:23.57
2018/06/17(日) 14:43:41.30
言いたいことがわからない
2018/06/17(日) 16:46:05.17
言っても無駄なんだろうが、そんなファイルを処理しようってのが間違ってると思う
2018/06/17(日) 19:18:43.97
>>676
処理したい時はどうすればいいですかね。
処理したい時はどうすればいいですかね。
2018/06/17(日) 19:23:59.83
POSIXで。
2018/06/17(日) 19:24:04.76
Windowsだと%TEMP%で一時ファイルの格納場所が指定できますがUnixではそういう環境変数はないのですか?
$TEMPとか
$TEMPとか
2018/06/17(日) 19:27:47.07
>>669
basenameって拡張子消えるよね?
basenameって拡張子消えるよね?
2018/06/17(日) 19:28:33.83
>>679
誰に対して使用して欲しいのか分からないな
誰に対して使用して欲しいのか分からないな
2018/06/17(日) 19:40:16.19
>>680
消せと言えばね
消せと言えばね
2018/06/17(日) 19:43:21.15
>>679
TMPDIR
かな
/tmp
が古からあるからな。TMPDIRが設定されていたら(OSとして初期設定されているか、なんらかの形でTMPDIR設定されてたら)TMPDIR。設定されてなかったら普通に /tmp かな
TMPDIR
かな
/tmp
が古からあるからな。TMPDIRが設定されていたら(OSとして初期設定されているか、なんらかの形でTMPDIR設定されてたら)TMPDIR。設定されてなかったら普通に /tmp かな
2018/06/17(日) 19:45:54.91
2018/06/17(日) 20:07:00.69
>>681
一応、TMPDIRはPOSIX標準環境変数らしい。 tmpfile(3)やmkstem(3)なんぞはPOSIXとしてはTMPDIRを参照しろとはなってないらしい
が、実装するならTMPDIR参照するだろうし、してる。ちゃんとtmpfile(3)やmkstem(3)やmktemp(1)などを使っていれば、誰でもなんだろうけどね
一応、TMPDIRはPOSIX標準環境変数らしい。 tmpfile(3)やmkstem(3)なんぞはPOSIXとしてはTMPDIRを参照しろとはなってないらしい
が、実装するならTMPDIR参照するだろうし、してる。ちゃんとtmpfile(3)やmkstem(3)やmktemp(1)などを使っていれば、誰でもなんだろうけどね
2018/06/17(日) 20:58:57.79
>>685
それってPOSIX shellの話なの?
それってPOSIX shellの話なの?
2018/06/17(日) 21:18:57.03
シェルじゃなくてシステム
2018/06/17(日) 21:19:01.81
>>686
何を聞いてるのかわからん
何を聞いてるのかわからん
2018/06/17(日) 21:19:45.24
俺…POSIXだったのか…?
2018/06/17(日) 21:59:03.03
関数のなかってalias使えないっぽいね
somefnc() {
alias AAA='pwd'
AAA
}
# → AAA: command not found
somefnc() {
alias AAA='pwd'
AAA
}
# → AAA: command not found
2018/06/17(日) 23:04:57.63
6.6 Aliases
...
Aliases are expanded when a function definition is read, not when the function is executed, because a function
definition is itself a compound command. As a consequence, aliases defined in a function are not available until
after that function is executed.
somefnc () { alias AAA='pwd'; }
somefnc
AAA
otherfnc () { AAA; }
otherfnc
...
Aliases are expanded when a function definition is read, not when the function is executed, because a function
definition is itself a compound command. As a consequence, aliases defined in a function are not available until
after that function is executed.
somefnc () { alias AAA='pwd'; }
somefnc
AAA
otherfnc () { AAA; }
otherfnc
2018/06/18(月) 03:25:19.77
aaa="cat /etc/*release | grep -E '^NAME='"
echo ${aaa}
上を実行すると、
$ ./hoge.sh
cat /etc/os-release | grep -E '^NAME='
こうなってしまいます。
cat 〜の結果をaaaに入れる方法教えて欲しいです。
echo ${aaa}
上を実行すると、
$ ./hoge.sh
cat /etc/os-release | grep -E '^NAME='
こうなってしまいます。
cat 〜の結果をaaaに入れる方法教えて欲しいです。
2018/06/18(月) 03:35:59.29
自己レス
evalで出来ました
evalで出来ました
2018/06/18(月) 07:01:47.43
>>690
関数の中でaliasが使えないと言うよりか、
関数の定義が実行された時点でのalias情報が反映される。
つまりシェルスクリプトを上から実行していって、
somefunc()関数定義文が見つかると、
この関数 "全体" に対して、alias展開処理が行われてから関数が定義される
だからsomefunc()関数定義文よりも前にaliasが設定されていれば
そのとおりに展開されるが、関数の中はすでにalias展開済みなので
もう処理されない
関数の中でaliasが使えないと言うよりか、
関数の定義が実行された時点でのalias情報が反映される。
つまりシェルスクリプトを上から実行していって、
somefunc()関数定義文が見つかると、
この関数 "全体" に対して、alias展開処理が行われてから関数が定義される
だからsomefunc()関数定義文よりも前にaliasが設定されていれば
そのとおりに展開されるが、関数の中はすでにalias展開済みなので
もう処理されない
2018/06/18(月) 07:11:33.65
ちなみにこれだとうまくいく
somefnc() {
alias AAA='pwd'
eval AAA
}
evalは実行する段階でalias展開されるようだ
evalで実行する文は、実行段階ならないと
わからないのだから当然ではあるが
somefnc() {
alias AAA='pwd'
eval AAA
}
evalは実行する段階でalias展開されるようだ
evalで実行する文は、実行段階ならないと
わからないのだから当然ではあるが
2018/06/18(月) 08:15:26.93
2018/06/18(月) 09:27:00.32
なるほど。大阪だけにおしゃかになったわけだな
2018/06/18(月) 09:36:50.09
は?
2018/06/18(月) 09:40:49.35
うちの研究室もすごいことになった。
ところで前々から関数のなかで alias が展開されないのを歯痒くおもっていたので
eval 使えばいいというのは非常に有益な Tips だわ。
ところで前々から関数のなかで alias が展開されないのを歯痒くおもっていたので
eval 使えばいいというのは非常に有益な Tips だわ。
2018/06/18(月) 10:09:39.01
あまりにもPOSIX、POSIXしつこいから、POSIXでNGにしたったわ
2018/06/18(月) 10:13:14.51
PSOIXでいこう
2018/06/18(月) 10:15:28.33
P0SIX(いやがらせ)
2018/06/18(月) 10:20:36.56
P051X
2018/06/18(月) 10:23:39.71
ぽじっくす
2018/06/18(月) 17:53:22.33
706名無しさん@お腹いっぱい。
2018/06/18(月) 20:47:12.932018/06/19(火) 04:10:29.03
関数の中、もしくはmakefileやcrontabで
aliasを使いたい状況っていうのがよくわからないが
どんなときに使うの?
aliasではなく変数とかじゃ駄目なの?
aliasを使いたい状況っていうのがよくわからないが
どんなときに使うの?
aliasではなく変数とかじゃ駄目なの?
2018/06/19(火) 04:54:42.99
自分は引数を取らず固定されたフィルタはaliasで定義することにしている
例えばeraelコマンド(ERAce Empty Line)。
alias erael='sed -e "/^$/d"'
ただ大抵はシェルスクリプトの先頭に記述するのであなたの言う通り関数の中で宣言する意図は分からん。
例えばeraelコマンド(ERAce Empty Line)。
alias erael='sed -e "/^$/d"'
ただ大抵はシェルスクリプトの先頭に記述するのであなたの言う通り関数の中で宣言する意図は分からん。
2018/06/19(火) 05:16:14.31
つづりeraseやで
2018/06/19(火) 05:53:06.78
2018/06/19(火) 06:00:33.38
2018/06/19(火) 06:15:17.17
関数とエイリアスの使い分けに意味はあるの?
使用メモリ?性能?
使用メモリ?性能?
2018/06/19(火) 06:31:47.07
2018/06/19(火) 07:04:14.39
みんな知ってるかい?
関数の中で関数を定義できるってことを
foo() {
bar() {
echo bar
}
}
foo
bar
関数の中で関数を定義できるってことを
foo() {
bar() {
echo bar
}
}
foo
bar
2018/06/19(火) 07:22:52.49
全角字下げやめてくれ
コピペで試せん
コピペで試せん
2018/06/19(火) 07:27:20.24
foo() {
bar() {
echo bar
}
}
foo
bar
bar() {
echo bar
}
}
foo
bar
2018/06/19(火) 08:03:40.13
5chに貼られたソースコードをコピペするってwセキュリティ意識ゼロかよw
絶対こんなの相手に発注したくねぇww
絶対こんなの相手に発注したくねぇww
2018/06/19(火) 13:37:44.18
アクalias飲みてぇ
2018/06/19(火) 18:46:56.46
>>717
たかが数行のソースが危険かどうかもわからん奴には発注したくないな
たかが数行のソースが危険かどうかもわからん奴には発注したくないな
2018/06/20(水) 02:21:04.28
somefunc() {
echo "${1:='need a arg'}"
}
のような関数を作ったのですが引数なしで起動すると
-bash: $1: この方法で割当はできません
と怒られるのですがどうすればいいですかね。
echo "${1:='need a arg'}"
}
のような関数を作ったのですが引数なしで起動すると
-bash: $1: この方法で割当はできません
と怒られるのですがどうすればいいですかね。
2018/06/20(水) 03:20:33.94
somefunc() {
arg="$1"
echo "${arg:='need a arg'}"
}
arg="$1"
echo "${arg:='need a arg'}"
}
2018/06/20(水) 03:34:23.66
>>721
ありがとうございます!
できました!
すいませんが、もしよければなぜ直接引数に:=変数置換を適用できないのか教えていただけないでしょうか。
例えば${1:-aaa}などはごく普通にできるので、不思議です。
ありがとうございます!
できました!
すいませんが、もしよければなぜ直接引数に:=変数置換を適用できないのか教えていただけないでしょうか。
例えば${1:-aaa}などはごく普通にできるので、不思議です。
2018/06/20(水) 05:12:57.83
bash: $1: この方法で割当はできません
bash: $1: cannot assign in this way
代入文を使って位置パラメータへの代入を行うことはできません。
Positional parameters may not be assigned to with assignment statements.
bash: $1: cannot assign in this way
代入文を使って位置パラメータへの代入を行うことはできません。
Positional parameters may not be assigned to with assignment statements.
2018/06/20(水) 06:53:00.27
すべての言語で引数に対する代入は禁止されればいいのに
2018/06/20(水) 07:57:59.37
引数に代入できる言語って例えば?
2018/06/20(水) 08:43:18.41
ば…bat
2018/06/20(水) 10:20:31.09
それ言語?
2018/06/20(水) 11:38:13.87
Cだとargvは一度どこかに書き出さないと置換とか操作できないよね。
2018/06/20(水) 12:45:30.95
>>728
別に直接書き換えもできる。constを「自分で」付ければできないようにもできるけど
Cで書き換えるのは危険すぎるだけだな。配列/文字列等のメモリ境界保護なんてないから。OSによってはargvがメモリ保護域にあるのもあるだろけど
別に直接書き換えもできる。constを「自分で」付ければできないようにもできるけど
Cで書き換えるのは危険すぎるだけだな。配列/文字列等のメモリ境界保護なんてないから。OSによってはargvがメモリ保護域にあるのもあるだろけど
2018/06/20(水) 12:48:49.26
>>728
argv の指す先は変更できないけど argv 自体は変更し放題
argv の指す先は変更できないけど argv 自体は変更し放題
2018/06/20(水) 12:56:35.45
>>730
argvの指す先(char **argv/*argv[]の中身/値でいいの?)も変更できるよ
argv = myArgv;
argv[1] = myArg;
argv[1][0] = myChar;
どれもできる
argvの指す先(char **argv/*argv[]の中身/値でいいの?)も変更できるよ
argv = myArgv;
argv[1] = myArg;
argv[1][0] = myChar;
どれもできる
2018/06/20(水) 15:25:21.41
ああそうか。728だけど,すごいまぬけな発言をしてたわ。
Cでのargvはあくまで約束事としての変数名だからなんの保護・制約も掛けられてないのか。
一方シェルスクリプトでは引数変数を明確に他と区別できるようになってる。
ただし半保護状態。
Cでのargvはあくまで約束事としての変数名だからなんの保護・制約も掛けられてないのか。
一方シェルスクリプトでは引数変数を明確に他と区別できるようになってる。
ただし半保護状態。
2018/06/21(木) 05:57:06.66
script(1)コマンドかそれと似たCLI記録ツールで、
~/.profile(←ここに~/.bashrcなどを読みこむコマンドが書いてある)を読み込ませたいのですがどうすればいいですかね。
~/.profile(←ここに~/.bashrcなどを読みこむコマンドが書いてある)を読み込ませたいのですがどうすればいいですかね。
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【鮭】20代女性の車のドアノブに体液、不同意わいせつ未遂の容疑で広島市安佐北区の30歳無職男を逮捕 [nita★]
- 渡邊渚「性を売ってるくせに」批判に反論 幻滅「これが日本の現状だよなー」「『渾身の下着!』というような意味でやってない」★3 [Ailuropoda melanoleuca★]
- 【生成ポルノで初】AI生成の児童ポルノ画像の所持疑いで元教諭を初摘発… [BFU★]
- 鈴木農相、地元JAから借入金 おこめ券巡り利害誘導との批判も★2 [安倍聖帝★]
- トランプ米大統領、「台湾保証実行法案」に署名 法案提出議員「支配しようとする中国に我々が断固として立ち向かう」 ★3 [お断り★]
- 【格闘技】朝倉未来「てめえ、今からやってやろうか?」 前代未聞のブチギレ! 関東最大級ギャングの元ボスと一触即発 [冬月記者★]
- 日本人「みんなちがって、みんないい?」「ルールがーマナーがー協調性がー郷に入れば郷に従えだよ」一丸となって頑張ろう🙆」 [289765331]
- 【高市悲報】プリキュア「いま私たちは環境問題に関心があるの」 プリオタ「ギェェェェェ思想が強すぎる!!」大炎上🔥 [762037879]
- 【01:45NHK~】サッカーW杯2026グルーブ分け組み合わせ抽選会いよいよスタート! ★2 [339712612]
- 女国会議員「夫がサンドイッチ用に6枚切りの食パンを買ってきました…」 ツイ民「6枚切りでもレシピあるよ」 女国会議員(スゥ…) [279254606]
- 抜け忍ってエッチな言葉じゃないの?
- 【悲報】日本人、気づき始める「高市早苗総理、なんか思ってたのと違う…」
