X



シェルスクリプト総合 その27
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
垢版 |
2018/05/03(木) 17:54:23.25
シェルスクリプトの総合スレです。
□お約束
・特記なき場合は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/
0670名無しさん@お腹いっぱい。
垢版 |
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
0671名無しさん@お腹いっぱい。
垢版 |
2018/06/17(日) 08:19:10.40
できればsedでやりたいことなんですが
aaa
<<
bbb
>>
もしくは
aaa
<<bbb>>
というようなファイルがあったとしてaaaの次行から「>>」を含む行までを読み出したいです。
(aaaが存在する行はすでに具体的な数値で判明しています; ここでは42行目とします)
特に二番目の場合には sed -n -e '43,/>>/p'とやると43行目に「>>」があるのに見つけてくれません。
なにか手助けをおねがいします。
0672名無しさん@お腹いっぱい。
垢版 |
2018/06/17(日) 09:24:18.61
>>671
sed -e '42,/>>/!d' -e 42d
0679名無しさん@お腹いっぱい。
垢版 |
2018/06/17(日) 19:24:04.76
Windowsだと%TEMP%で一時ファイルの格納場所が指定できますがUnixではそういう環境変数はないのですか?
$TEMPとか
0683名無しさん@お腹いっぱい。
垢版 |
2018/06/17(日) 19:43:21.15
>>679
TMPDIR
かな
/tmp
が古からあるからな。TMPDIRが設定されていたら(OSとして初期設定されているか、なんらかの形でTMPDIR設定されてたら)TMPDIR。設定されてなかったら普通に /tmp かな
0684名無しさん@お腹いっぱい。
垢版 |
2018/06/17(日) 19:45:54.91
>>679,683
>TMPDIRが設定されていたら〜
って、TMPDIRを意識していればね。当然のように、んなの知らん、/tmp 一択ってのも普通にある
0685名無しさん@お腹いっぱい。
垢版 |
2018/06/17(日) 20:07:00.69
>>681
一応、TMPDIRはPOSIX標準環境変数らしい。 tmpfile(3)やmkstem(3)なんぞはPOSIXとしてはTMPDIRを参照しろとはなってないらしい
が、実装するならTMPDIR参照するだろうし、してる。ちゃんとtmpfile(3)やmkstem(3)やmktemp(1)などを使っていれば、誰でもなんだろうけどね
0691名無しさん@お腹いっぱい。
垢版 |
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
0692名無しさん@お腹いっぱい。
垢版 |
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に入れる方法教えて欲しいです。
0694名無しさん@お腹いっぱい。
垢版 |
2018/06/18(月) 07:01:47.43
>>690
関数の中でaliasが使えないと言うよりか、
関数の定義が実行された時点でのalias情報が反映される。

つまりシェルスクリプトを上から実行していって、
somefunc()関数定義文が見つかると、
この関数 "全体" に対して、alias展開処理が行われてから関数が定義される

だからsomefunc()関数定義文よりも前にaliasが設定されていれば
そのとおりに展開されるが、関数の中はすでにalias展開済みなので
もう処理されない
0695名無しさん@お腹いっぱい。
垢版 |
2018/06/18(月) 07:11:33.65
ちなみにこれだとうまくいく

somefnc() {
  alias AAA='pwd'

  eval AAA
}

evalは実行する段階でalias展開されるようだ
evalで実行する文は、実行段階ならないと
わからないのだから当然ではあるが
0699名無しさん@お腹いっぱい。
垢版 |
2018/06/18(月) 09:40:49.35
うちの研究室もすごいことになった。
ところで前々から関数のなかで alias が展開されないのを歯痒くおもっていたので
eval 使えばいいというのは非常に有益な Tips だわ。
0707名無しさん@お腹いっぱい。
垢版 |
2018/06/19(火) 04:10:29.03
関数の中、もしくはmakefileやcrontabで
aliasを使いたい状況っていうのがよくわからないが
どんなときに使うの?
aliasではなく変数とかじゃ駄目なの?
0708名無しさん@お腹いっぱい。
垢版 |
2018/06/19(火) 04:54:42.99
自分は引数を取らず固定されたフィルタはaliasで定義することにしている
例えばeraelコマンド(ERAce Empty Line)。
alias erael='sed -e "/^$/d"'
ただ大抵はシェルスクリプトの先頭に記述するのであなたの言う通り関数の中で宣言する意図は分からん。
0713名無しさん@お腹いっぱい。
垢版 |
2018/06/19(火) 06:31:47.07
>>712
いやまったく大差ない。
ただただaliasというだけ
分かってると思うが俺は別に「使え!」なんて言ってないから
そんな気にする必要ないぜ。
個人的な問題だから。
0717名無しさん@お腹いっぱい。
垢版 |
2018/06/19(火) 08:03:40.13
5chに貼られたソースコードをコピペするってwセキュリティ意識ゼロかよw
絶対こんなの相手に発注したくねぇww
0720名無しさん@お腹いっぱい。
垢版 |
2018/06/20(水) 02:21:04.28
somefunc() {
 echo "${1:='need a arg'}"
}
のような関数を作ったのですが引数なしで起動すると
-bash: $1: この方法で割当はできません
と怒られるのですがどうすればいいですかね。
0722名無しさん@お腹いっぱい。
垢版 |
2018/06/20(水) 03:34:23.66
>>721
ありがとうございます!
できました!
すいませんが、もしよければなぜ直接引数に:=変数置換を適用できないのか教えていただけないでしょうか。
例えば${1:-aaa}などはごく普通にできるので、不思議です。
0723名無しさん@お腹いっぱい。
垢版 |
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.
0729名無しさん@お腹いっぱい。
垢版 |
2018/06/20(水) 12:45:30.95
>>728
別に直接書き換えもできる。constを「自分で」付ければできないようにもできるけど
Cで書き換えるのは危険すぎるだけだな。配列/文字列等のメモリ境界保護なんてないから。OSによってはargvがメモリ保護域にあるのもあるだろけど
0731名無しさん@お腹いっぱい。
垢版 |
2018/06/20(水) 12:56:35.45
>>730
argvの指す先(char **argv/*argv[]の中身/値でいいの?)も変更できるよ
argv = myArgv;
argv[1] = myArg;
argv[1][0] = myChar;
どれもできる
0732名無しさん@お腹いっぱい。
垢版 |
2018/06/20(水) 15:25:21.41
ああそうか。728だけど,すごいまぬけな発言をしてたわ。
Cでのargvはあくまで約束事としての変数名だからなんの保護・制約も掛けられてないのか。
一方シェルスクリプトでは引数変数を明確に他と区別できるようになってる。
ただし半保護状態。
0733名無しさん@お腹いっぱい。
垢版 |
2018/06/21(木) 05:57:06.66
script(1)コマンドかそれと似たCLI記録ツールで、
~/.profile(←ここに~/.bashrcなどを読みこむコマンドが書いてある)を読み込ませたいのですがどうすればいいですかね。
0734名無しさん@お腹いっぱい。
垢版 |
2018/06/21(木) 06:34:26.14
>>733
#!/bin/sh
exec /bin/bash --init-file "$HOME"/.profile "$@"

こういうスクリプトを書く
ファイル名を mysh でホームに保存したとして、次のようにして script に使わせる

env SHELL="$HOME"/mysh script
0738名無しさん@お腹いっぱい。
垢版 |
2018/06/21(木) 09:45:45.51
bashの場合、インタラクティブでログインシェルでなければ.bashrcを読むはずだけど、それじゃ足らんの?
0740名無しさん@お腹いっぱい。
垢版 |
2018/06/21(木) 15:25:56.39
733です。すいません。もうひとつ訊きたいことがあるのですが
script(1)実行中はCOLUMNS=80,LINES=25に固定したいです。
しかしそのmyshに
export COLUMNS=80
などと記述しても反映されません。
~/.profileなどでは特にCOLUMNSの値を設定している訳ではないです。
これどうすればいいですかね
0741名無しさん@お腹いっぱい。
垢版 |
2018/06/21(木) 17:29:46.87
stty cols 80 rows 25
なんかLINESもってとこから、ターミナルのウィンドウサイズなんぞもってぽいけど、それは個々のターミナルアプリ次第&一方通行っぽい(COLUMNSの値を設定している訳ではないのはそゆこと)けど
0742名無しさん@お腹いっぱい。
垢版 |
2018/06/22(金) 07:10:56.19
シェルスクリプトってeval使えばメタプログラミングっぽいことできるよね。
例えば引数をfor文で増加さしてeval arg$i=\$$iみたいな。
0744名無しさん@お腹いっぱい。
垢版 |
2018/06/22(金) 08:56:09.19
evalは一番最初に現れたプリミティブなメタプログラミング機能だからまあ当然だな。
ちな最初にeval を発明した言語はLisp な。
0747名無しさん@お腹いっぱい。
垢版 |
2018/06/23(土) 10:04:22.34
evalは強力すぎて危険だからどの言語でも濫用はevil扱いだと思う。
REPLみたいにevalがぴったりした応用もあるから禁止はできんし、
シェルスクリプトは比較的ミニマムな言語だからevalしか解がないケースも多いけど。
0748名無しさん@お腹いっぱい。
垢版 |
2018/06/23(土) 11:22:58.87
「ミニマルな言語」って他には例えばなに?
それLLとはまた違うの?
いや煽ってるんではなくて単純に訊ねたい。
0749名無しさん@お腹いっぱい。
垢版 |
2018/06/23(土) 11:42:26.04
コマンド置換の入れ子の限界を試そうと思って
$ i=1; while true; do echo $i; eval $( (yes '$(echo' | head -n $i | tr -d '\n'); (yes ')' | head -n $i | tr -d '\n') ); : $((i++)); done
↑こんなコードを実行してみた。
100あたりから面白いくらいに遅くなっていく
しかし500くらいまで試したけど表示は続き、限界を探る目的は達成できなかった。
0751名無しさん@お腹いっぱい。
垢版 |
2018/06/23(土) 14:46:23.27
eval関連なんですがaliasの出力結果をevalする方法を教えてください。
具体的にはroot権限でlsがしたいのですが、その時通常のlsと同じオプションを付けて実行したいのです。
ですので(通常の状態での)alias lsの結果を変数かなにかに格納してそれを実行しようと思ったのですが良い方法が思い付きません。
そのコマンド自体もaliasにしたい(具体的にはls@rootコマンドとしてalias ls@root=の形で定義したい)です。

どうかよろしくお願いします。
0752752
垢版 |
2018/06/23(土) 14:52:25.95
すいません。一番上の行は無視してください。
evalでできるかなと考えてたプロセスが漏れてしまっただけです。
多分このアプローチは間違っているので無視してください。
0759名無しさん@お腹いっぱい。
垢版 |
2018/06/24(日) 22:14:10.69
>>748
データ型が少ないって意味でTclとかかな。
でもTclには文字列型の他に連想配列があるのよね。
POSIX shellの範囲内だと引数配列を除けばホントに文字列しかないので。
0760名無しさん@お腹いっぱい。
垢版 |
2018/06/26(火) 16:44:06.12
こんにちは

ド素人です。
VPSの立ち上げ時にスタートアップシェルスクリプトを使って効率化したいです。

とあるwgetを叩くと、user名とパスワード、パスワードの再入力を求められるのですが、
このuser名、パスワードをシェルスクリプトで入力させるにはどうしたらよいでしょうか。
0761名無しさん@お腹いっぱい。
垢版 |
2018/06/26(火) 17:04:46.28
wgetでgithub上にある既存のシェルスクリプトを叩くと
ユーザー名とパスワードを聞かれるのですが、
その入力を自動化したいという意味です。

github上のシェルスクリプトは変更できません・・・
0764名無しさん@お腹いっぱい。
垢版 |
2018/06/26(火) 17:29:12.30
>>761
相手側の要求に従ったuser名パスワードの提供方法をwgetでするとよいでしょう
どのVPS?どういう相手側のサービス?その使ったというはGitHubのどれ?
https://gist.github.com/kevinold/216077/4d725773b46a2ac32c0f5a689339d3da004d7f5d
これでいいのか?適当にぐぐったらVPSだしwget使ってるしw

>>762
まあ、なんかセットアップでコマンド叩いたりするのだろう。そういえばwgetで認証できなかったら再入力なんて求められないよな...??あったかな??
0766名無しさん@お腹いっぱい。
垢版 |
2018/06/26(火) 18:04:40.17
httpのBASIC認証やftpのならそれで問題はないよね。普通にBASIC認証でそのオプションを教えてっていうことだけかな
0768名無しさん@お腹いっぱい。
垢版 |
2018/06/26(火) 19:26:12.11
wgetが書かれたシェルスクリプトを呼び出すシェルスクリプトを書きたいように見えるが…
まあ質問が日本語的に不自由すぎるね
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況