1 名前:名無しさん@お腹いっぱい。 mailto:sage [2017/03/20(月) 12:07:26.41 .net] シェルスクリプトの総合スレです。 □お約束 ・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。 Linuxユーザは/bin/shの正体がbashまたはdashなので特に注意。 FreeBSDユーザは/bin/shの正体がashなので注意。 v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。 src.illumos.org/source/xref/illumos-gate/usr/src/cmd/sh/ heirloom.sourceforge.net/sh.html ・csh/tcshのシェルスクリプトは推奨されません。 (理由は「csh-whynot」でググれ) ・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。 manや参考リンクを見ましょう。 aproposないしはman -kでそれらしい単語による簡単な検索もできます。 ・シェルで使えるワイルドカード等は正規表現ではありません。 正規表現の話題はスレ違い(正規表現スレへ) ・シェルスクリプトのことをシェルってゆーな □初心者へのアドバイス: ・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも awkまたはperlの方が適した処理にはそちらを使いましょう。 ・知らないコマンドが出てきたらmanを引きましょう。 ・思い通りに動かないときは、まずは sh -x でトレースしましょう。 □回答者への注意事項: ・シェルスクリプトでの処理方法を質問しているのに、よくわからずに 「そういうのはperl使いましょう」と回答するのはやめましょう。 安易にperlに逃げずにシェルスクリプトで処理するのが頭のいいやり方。 前スレ シェルスクリプト総合 その25 echo.2ch.net/test/read.cgi/unix/1439563321/
575 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/05(月) 23:15:38.51 .net] 545から漂う頭の悪さよ
576 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/05(月) 23:21:32.35 .net] >>558 のそれ「解答」じゃないじゃん。 無理って言われてるんだぞ? 理解できてる?
577 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/05(月) 23:23:14.97 .net] もういいじゃん ほっとけよ
578 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/05(月) 23:23:16.19 .net] どういう態度取るべきとは思わないけど、 相手を不快にさせたら得られるはずの回答も得られなくなる可能性が上がるよ。 それでよければご自由に。
579 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/05(月) 23:26:33.25 .net] 出力が色制御してきたら取り除いたりとか、マルチプロセスとかで変なところでブッタ斬り/ミックスされないように同期取ったりとか考えてたけど俺には無理だからもういいや
580 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/05(月) 23:33:38.33 .net] >>566 やりたいこと > 標準出力の内容を緑に、標準エラー出力の内容を > 赤にしたいんだけどどうすればいい? 標準出力の内容を緑にする・・・簡単 標準エラー出力の内容を赤にする・・・? >>558 で明らかになったこと ・・・ 標準出力と標準エラー出力を入れ替える方法 ここから標準エラー出力の内容を赤にするには 標準出力と標準エラー出力を入れ替えれて 処理すればいいって気づくよね?
581 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/05(月) 23:47:07.49 .net] >>570 ん? それだと今度は標準出力が (標準エラー出力に複製されたので) パイプを通らなくなるから、 標準出力の内容 (今は標準エラー出力に出力されている) を緑にできないんじゃ?
582 名前:もしかして同時じゃなくていいってこと? [] [ここ壊れてます]
583 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 00:20:35.13 .net] もうほっとけ 標準出力、標準エラー出力に関する便利な小ネタでも教えてやろうかと思ったけどやめとくわ
584 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 01:01:07.43 .net] >>571 片方ずつしか処理できないなら、 2回やれば両方できるだろ? っていうかそれぐらいわかるだろw
585 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 01:01:45.64 .net] >>572 > 標準出力、標準エラー出力に関する便利な小ネタでも教えてやろうかと思ったけどやめとくわ おせーておせーて
586 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 01:03:40.69 .net] |& ←このパイプは標準出力標準エラー出力ともに通すよ。 ただ質問者さんが望んでいるのは「標準出力か標準出力かが区別できる状態でのパイプ通過」だろうから、 それはちょっと無理なんじゃないかな。 あと態度がデカすぎる。一度死んだほうがいいと思う。
587 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 01:14:26.43 .net] >>573 まさかコマンド二回回すの? 標準出力と標準エラー出力分ける為だけに? それ一時ファイル作るより余程冗長だぞw もう一度シェルっていうかコンピュータの仕組みを勉強しなおしてきな
588 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 01:45:01.59 .net] だから一時ファイルを作るとストリーミングに できなくなるからだめなんだって さっきも書いたろ
589 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 01:47:17.52 .net] >>575 やっぱり>>558 が今のところ一番シンプルな解みたいだね。 てか、標準出力と標準エラー出力を別々にファイルに吐き出せるんだから、 別々のプログラムにパイプでつなげられる機能があっても良いと思うんだけどね
590 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 02:48:45.93 .net] 君たぶんだけど意思疎通に係わる障害持ってるから病院で診てもらったほうがいいよ。 知り合いにそういう調子の会話する人がいて、ある日会社で大きな事件を起こして辞めさせられたあと 病院で検査したらそういう系統の精神病だったからさ。 煽りとかじゃなくて、君はどうも社会で孤立してそうだから、助けになりたい。
591 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 03:23:52.46 .net] いや、おちょくってるだけだろ まともに相手するだけ無駄やぞ
592 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 04:17:47.54 .net] ここに限らず、質問系のスレにたまに沸くアレでしょ 5chが過疎って最近あんま見てなかったから なんか懐かしい感じするわw
593 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 10:26:50.47 .net] レス内容が煽りだけになったらおしまいw
594 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 20:25:23.40 .net] あっちで粘着してるみたいだな 久々にアレな奴を見たわ
595 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 21:23:37.44 .net] 入力リダイレクトで複数ファイルを一度で流し込むのはどうしたら良いのですか?
596 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 21:44:48.81 .net] catしてパイプ
597 名前:watarie [2018/03/06(火) 22:03:33.11 .net] よろしくお願いします。 mac で bashです。 mdfindからパイプつないだ先でcpしたら 検索が間に合わなかったのかコピーし損ねがでてきます。 再度コピーしそこねたファイル名リストを同じようにこれに掛けると、 幾つか成功していくつかはコピーし損ねます。 function readMdfind() { while read LINE; do mdfind "kMDItemFSName == "${LINE}" || kMDItemDisplayName == "${LINE%.*}"" | awk 'NR==1' | xargs -J % cp -p "%" "$1" 2>/dev/null done <${2} 引数の1はファイル名のリストが入ったテキストで、2はコピー先のフォルダになります。 ファイル名は殆どが一意にしてあるので、とりあえずヒットしたら良い感じです。 一度で取りこぼしのない良い方法はありませんでしょうか。
598 名前:watarie [2018/03/06(火) 22:05:40.25 .net] 引数の件1と2逆でした 惑わせてしまい申し訳ありません。 正しくは1がコピー先フォルダで2
599 名前:がファイル名のリストです。 [] [ここ壊れてます]
600 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 22:33:41.80 .net] >>585 回答ありがとうございます。 ということはそのまま cat hoge huga | command で、いいってことですか。なるほど。 レスつくまで色々ググって調べてみたのですが command <( cat hoge huga ) でも全く同じ動作ですか?
601 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 23:27:44.61 .net] >>588 二番目の方法,たぶんコマンドラインで試して成功したから書き込んでるんだろうけど, それはプロセス置換と言って Bash筆頭に幾つかのシェルの独自拡張だからシェルスクリプトにするときは シェバンを #! /usr/bin/env bash か #! /bin/bash とかにする必要がある。 cat hoge huga | somecommand で代替できることに可搬性を犠牲にするのは避けたいだろうから (つまり #! /bin/sh というシェバンを捨てるのは勿体無いということ) <(cat hoge huga) は避けれる時は (特にシェルスクリプトで使う時) 避けといたほうがいいんじゃないかな。
602 名前:586 mailto:sage [2018/03/06(火) 23:29:38.39 .net] 5行目あたりの日本語がおかしい。けど国語力ないので自然に直すの無理。 察してくれ。
603 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 23:43:28.43 .net] >>589 なるほど! #!/bin/sh が必ずbashにリンクされてるとは限らないから、 拡張表現で書かなくて済む場合は確かに可搬性を優先した方がいいですね。 ありがとうございました。
604 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/06(火) 23:49:32.51 .net] >>586 mdfindを知らんので問題解決に直接ならないけれど`done < ${2}`ではなく`done < "$2"`のほうがいいよ〜 もっと言うなら`cat "$2" | while read LINE;`のほうがいいかもね〜 * POSIX sh互換シェルは変数名に数字が来たらそこで読み取りを中断するので波括弧で変数名の範囲を明示しなくていい * 変数$LINEに^Dとかが渡された時catコマンドと<リダイレクトで違いがある 短いんだけど参考: pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_01
605 名前:588 mailto:sage [2018/03/06(火) 23:58:01.42 .net] あー! さらに調べたら、よくわかりました。 #!/bin/sh でbashを起動したらbashの拡張とか使えなくなっちゃうんですね。 だからシェバンを書き換える必要があると… そういう意味だったんですね。 (ちゃんとmanにかいてありました) ためになりました。
606 名前:名無しさん@お腹いっぱい。 [2018/03/07(水) 07:20:57.39 .net] >>592 ん?どゆこと? $ cat file | cmd $ cmd < file で違いがあるってこと?そうは思えないんだけど…
607 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/07(水) 08:34:45.43 .net] $LINEに^Dってなんぞやってところだな
608 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/07(水) 08:37:52.19 .net] >>586 まずはエラーをnullに落とさずに表示させろ
609 名前:watarie [2018/03/07(水) 09:23:48.67 .net] >>592 さん
610 名前:watarie [2018/03/07(水) 09:32:33.42 .net] >>592 さん ありがとうございます。ちょっと英語で読解が難しいので時間を作って該当の箇所を読ませていただこうかと思います。 {2}の箇所を"2"に変更しました。 <の箇所をcatに変更しました。 非常に目に優しいくなりました。 読み込む箇所なので、怪しいと感じます。結果としては変わりませんでしたが、参照の箇所は興味がありますので読ませていただこうと思っています。英語で弱気になりますが^^; ありがとうございます。
611 名前:watarie [2018/03/07(水) 09:37:28.43 .net] >>596 さん すみません。確かにそうですよね。 初心者過ぎで逃げを当然にしてたバチがあたったようです。 吐き出したエラーは、 cp: /Volumes/Macintosh: No such file or directory cp: HD: No such file or directory などのファイルパスが、スペース区切りになってcp出来ませんでしたよというエラーでした。 ただ、検索に漏れた該当のファイルは何度めかにはヒットしますので上記のエラーとはならなかったということに。 spotlight特有のものだからと諦める
612 名前:オかないのか・・・ これがひょっとしたら手がかりになるかもしれませんが、わたしの力では全く・・・ [] [ここ壊れてます]
613 名前:watarie [2018/03/07(水) 09:45:34.86 .net] すみません、mdfindの検索結果のファイルパスが スペースで割れてしまってcpに渡されたということでした。たぶん^^;
614 名前:watarie [2018/03/07(水) 12:55:37.74 .net] 解けました!ありがとうございます! ダブルコーテーションを%の箇所で囲うのではなく、 1行取り出した先でパイプして囲えば良いと思い以下を試したところ出来ました。 mdfind "kMDItemFSName == "${LINE}" || kMDItemDisplayName == "${LINE%.*}"" | awk 'NR==1' | sed -e 's/^\(.*\)$/\"\1\"/' | xargs -J % cp -p % "$1" 2>/Users/mac10/Desktop/out エラー出力素晴らしいです! ありがとうございました!
615 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/07(水) 18:25:56.09 .net] ずっとageっぱなし…(小声)
616 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/07(水) 19:48:17.38 .net] mdfindとxargsに-0つけるのが定石だと思うけど、もう見てないかな。
617 名前:名無しさん@お腹いっぱい。 [2018/03/08(木) 00:41:50.66 .net] >>578 今更だけど、あるんだよね。誰も教えたくなかったんだね。
618 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 01:55:58.38 .net] まああるよね
619 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 07:30:07.37 .net] ヒントくらい出すか……。でもあいつに教えたくないんだよなぁ。 卑屈だけど、気持は分かるだろ? パイプに名前(ry
620 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 16:44:02.99 .net] それ使うと出力側はこんな感じかな while :;do sed -e 's/\(.*\)/^[[32m\1^[[m/' np1 & sed -e 's/\(.*\)/^[[33m\1^[[m/' np2 >&2; done
621 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 20:31:17.47 .net] >>607 野暮な指摘だが、sedを使わない printf '\e[32m%s\[0m' "$(cat)" の方が分かりやすくね? つーか printf ってそういう「整形した出力」の為のコマンドだろうし。
622 名前:604 mailto:sage [2018/03/08(木) 20:32:49.31 .net] >>695 ミスった… printf '\e[32m%s\e[0m' "$(cat)" だ。 こうすると "$(cat)" の部分で np1 を受けt[以下略]
623 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 20:51:46.21 .net] >>606 名前付きパイプ(mkfifo)はプロセスが2個あって 片方が出力側プロセス、片方側が入力側プロセスに 別れない限りストリーミングにすることができない (同一プロセスでは出力しながら入力ができないため) 今回の場合、標準出力と標準エラー出力の2つがあるから 出力側プロセス1個と入力側プロセス2個の合計3プロセスが必要になる つまり別プロセスとして起動しなければいけない もちろん出力の完了待ちのwaitも必要だし、作成したパイプの削除も必要。 特にCTRL+Cで中断された場合とか また万全を期してパイプ名が被ることも考慮してランダムな名前にしたい ここまで言えば名前付きパイプを使った方法は実装するのに行数がかかり 面倒な方法だと言うことがわかるだろう? また>>557 で書いたとおりbusyboxで動かす必要があるのだが、 そもそもbusyboxでmkfifoが存在しない場合もある ↑俺にとってはこっちのほうが重要
624 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 21:00:55.81 .net] もう来なくていいよ レス続けるならコテハン付けて
625 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 21:03:28.88 .net] 粘着かよ 気持ち悪い
626 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 21:03:48.79 .net] レス続けたのは俺じゃないんだがw
627 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 21:57:56.36 .net] うわ。まだ居たのかこのキチガイ… まあ放置が一番いいな。俺のこのレスも彼を発狂させる原因になるやもしれんし。
628 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 22:15:10.19 .net] まあ反論なく放置される(=俺の勝ち逃げ)という状況ってのが 俺にとっては一番であることには間違いないが で俺がレスしたのは、放置してないからだよ?w
629 名前:604 mailto:sage [2018/03/08(木) 22:33:08.10 .net] >>609 あ、しまった printf '\e' は GNU/Linux じゃないと動かないみたい。 Debian使ってんのがバレてしまったw FreeBSDとかでも動作させる為には printf '\033' とやる必要がある。
630 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 22:42:34.38 .net] >>609 出力 A 正常 出力 B 異常 出力 C 正常 の時 それだとACBまたはBACと表示されないか? まぁそれで良ければ良いんだけど
631 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 23:32:13.81 .net] ガチでアレな奴が粘着してるな ここまで気持ち悪い奴は滅多に見ない
632 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/08(木) 23:54:18.50 .net] >>556 exec > >(sed -e 's/\(.*\)/^[[32m\1^[[m/') exec 2> >(sed -e 's/\(.*\)/^[[33m\1^[[m/') 後は普通に処理を書けばおk
633 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/09(金) 01:48:35.86 .net] どんだけ答え知りたいんだ あっちのスレいけよこっちはこっちで楽しんでんだから
634 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/09(金) 22:50:21.96 .net] おいおい勘違いするな >>556 はbashやzshでのやり方を聞いてる。 POSIXの範囲でやりたいと言ってる俺ではない
635 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/09(金) 23:00:06.75 .net] そういや>>619 で思い出したけど、 busyboxのsedってなんか動きがおかしいんだよね。 (echo 1; sleep 5; echo 2; sleep 5) | sed 's/a/a/' 例えばこれを実行すると、1が表示されるのは5秒後になる debianだとすぐに表示されるのに。一行遅れて表示される だからsedは今回の俺の用途には使えなくてreadを使ってる
636 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 00:28:42.71 .net] >>622 Ubuntu ではおかしいみたいですね。 Debian と openSUSE の busybox では記述通りの動きでした。
637 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 01:03:52.34 .net] >>623 WSL上のUbuntuは問題なかった。 busyboxはビルドによって色々変わるだろうけど よく分からんね
638 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 01:06:54.08 .net] > openSUSE の busybox では記述通りの動きでした。 もしかして、sedはbusyboxじゃない方のsedになってない? WSL上のUbuntuに入れたbusyboxのsed ↓つまりこれを実行するとやっぱり5秒後に1と表示される (echo 1; sleep 5; echo 2; sleep 5) | busybox sed 's/a/a/' やっぱりbusyboxが実装してる簡易版sedの問題な気がする
639 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 01:08:10.50 .net] まあもともとbusyboxってそういうものだし とりわけ騒いだりはしないけどさ
640 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 02:15:25.24 .net] >>625 >>623 は busybox ash でシェルを起動して確認しています。 busybox sed 's/a/a/' にすると Debian も openSUSE も Ubuntu と同じ動作になりました。
641 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 09:07:03.16 .net] おーほんとだ。Busybox v1.22.1 on Debianでも同じような動きになる。 ここまでハッキリしたバグに遭遇したの久し振りだわ 単に離れてただけかもしれんが
642 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 09:38:16.90 .net] なにやら興味がある人がいるようでw なんで俺の用途で使えないかというと、例えばこんな感じに ユーザーのインタラクティブな入力を変換して出力したいから ↓ >(実際には画面に表示されない) の行がユーザーの入力 $ sh | sed 's/a/a/' > echo 1 > echo 2 1 > echo 3 2 見ての通りユーザーが入力したコマンドの結果が一つ遅れて表示される sedのよくあるユースケースでは問題ないんだろうけどね
643 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 12:15:21.67 .net] >>629 挙動が変わるツールは珍しいなと思いました。 busybox ash の中で sh | sed 's/a/a/' とすると、 Debian (v1.22.1) まとも Ubuntu (v1.22.1) 遅れる openSUSE (v1.21.1) まとも(sh プロンプトが表示される) CentOS (v1.15.1) まとも(sh プロンプトが表示される) Windows (v1.29.0) 遅れる でした。 ビルド時に引いているライブラリの差異なのでしょうか...
644 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 12:28:15.59 .net] バッファリングが影響してそうなのかもしれないけど 正規表現の実装の都合な気もする。 はたまたカーネル
645 名前:ェ関係してるのかシェルの設定でなんかあるのか 正直、そういう違いが有るんだね。気をつけておくよと 事実を受け止めるぐらいでで深追いする気力はないw 話変わるけど、何もしない関数の定義、 foo() : もしくは、echoするだけの関数の定義 foo(): echo foo この書き方ってPOSIX準拠だよね? bashやzshではエラーになった [] [ここ壊れてます]
646 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 15:57:33.44 .net] >>631 foo() echo foo ならzshは理解するぞ Bourne shell系はfoo() any-compound-commandだけ理解して foo() any-commandは理解しない
647 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 18:45:48.71 .net] >>631 POSIX準拠なのかはよくわかりませんが、sh ならば foo() foo1() echo "$1" で、sh でも bash でも動かすなら foo() { :; } foo1() { echo "$1"; } でいけると思います。
648 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 23:10:12.04 .net] 訂正 × foo(): echo foo ○ foo() echo foo >>632 ごめん、zshでは試していなかった。 今zsh入れてたマシン壊れてるんだったw 別の環境にzsh入れたらたしかに動いたね dash、ash、zsh では動いた bashだけ動かなかった
649 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/10(土) 23:17:51.17 .net] func() : ↑これ確かにシェバンを #! /bin/sh にすると通るけど #! /usr/bin/env bash にすると撥ねられるな。 pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_05 一応現行POSIXのシェル関数の定義はここに書いてあるけど、func() : は恐らく適合してるな。 多分bashの文法チェックが少しばかりおせっかいすぎるんだろう。 でもPOSIXに準拠した記法なのにエラーになるって嫌だなぁ
650 名前:632 mailto:sage [2018/03/10(土) 23:21:43.98 .net] あれ。yashでも「syntax error: a function body must be a compound command」って撥ねられるわ。 yashはかなり厳密にPOSIXに従ってる筈なんだけど…
651 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 00:25:29.87 .net] またちょうどよくシバンの話がw シェルスクリプトのファイルを直接実行するのではなく ライブラリとして他のスクリプトから読み込むだけの場合 シバンいらないよね? またその場合の拡張子ってどうしてる? シンタックスハイライトとか自動で適用させたいんだけど 余計なものはできるだけ排除したい
652 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 00:28:14.22 .net] >>635 そうなんだよね。あと > fname ( ) compound-command [io-redirect ...] ここにio-redirectが書けたのがびっくり どういう時に使えば良いんだろうか?
653 名前:632 mailto:sage [2018/03/11(日) 01:05:34.01 .net] >>638 俺は未インストールコマンドの処理に使ってる check_command() { type "$1" > /dev/null 2>&1 || { printf '%s%s\n' \ "$1" 'をインストールして下さい。' exit 1 } >&2 return $? } check_command "curl" こうするとエラーメッセージが標準出力に出ないからパイプ繋いでてもおかしなことになりにくい。 もっとも |& ←みたいなパイプなら無理だけど、そもそも標準エラー出力ごとパイプに使うなんて稀だろうという推測。
654 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 01:46:36.03 .net] >>639 いや、そうではなくて関数定義の最後に書けるんだなーって話 その例で言えば、こういう書き方ってこと (関数全体を別の所に出力したいときには便利か、うーん使うかな?) check_command() { type "$1" > /dev/null 2>&1 || { printf '%sをインストールして下さい。\n' "$1" exit 1 } } >&2 # ついでにどうでもいい所を俺の趣味で変更したw # exitもreturnに変えたい。もしくはexit_if_command_not_foundみたいな関数名にしたい > もっとも |& ←みたいなパイプなら無理だけど、そもそも標準エラー出力ごとパイプに使うなんて稀だろうという推測。 /dev/ttyに出力するって手もあるよ $ (echo stdout-a; echo stderr-a >&2; echo tty-a >/dev/tty) |& sed 's/a/b/' tty-a stdout-b stderr-b
655 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 02:00:39.65 .net] >>636 yash覚えた 最低限機能しかももってないと思われるashで動けば Bourne Shell 系全部でうごくだろうと思っていたから そういうこともあるんだなーって思った
656 名前:632 mailto:sage [2018/03/11(日) 02:47:31.38 .net] >>640 あ,そういうことか。勘違いしてたわw それはちょっと使い道思い付かん ところで, return $? ↑これ消した理由なに? C言語をやってるせいか関数が終了ステータスを返さないと不安で仕方無いんだけども, シェルスクリプトだと要らないのかな。今まで特にreturn行のせいで不具合が発生したこともなかったけれど。
657 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 11:42:23.58 .net] >>642 何も書いてなければ、その時点の$?がそのまま返るだろ? > C言語をやってるせいか関数が終了ステータスを返さないと不安で仕方無いんだけども, Ruby(最後に評価された値を返す)やってるとreturnなんて書かないんだがw
658 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 11:44:13.17 .net] > 今まで特にreturn行のせいで不具合が発生したこともなかったけれど。 まあ不具合は発生しないだろうね。 関数の最後でなにもしないなら、その時点の $? が返る所を $?を取り出してreturnの引数で$?を返すようにしただけだからw
659 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 13:19:13.21 .net] Cとか化石みたいな言語使ってる人って無駄が多いよね 生産性悪w
660 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 13:41:26.14 .net] そういうこと言う奴って大体Cが出来ないコンプレックス抱えてるんだよなぁ
661 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 13:44:23.08 .net] Cから学べること多いのになぁ
662 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 13:59:18.74 .net] Cはハードに近いところを表現するのに適してるから絶対に無くならないけどね。 化石だけど生活には欠かせない燃料みたいなもんかな。 Cで書かれてるシェルのスレで否定しちゃうのはちょっと痛いね。
663 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 14:52:52.42 .net] 俺はCを否定してないぞ。C以外を使っていれば returnしなくていい言語だってあることを知るだろうし、 returnを書くことに拘る必要はないってことだ
664 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 16:03:25.28 .net] >>643 ruby使ってたってreturn書くことあるだろ implicitとexplicitを状況に応じて使い分けることが大事
665 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 16:26:06.07 .net] 山月記ってアニメ化されないの?
666 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 16:39:38.95 .net] >>650 ルビ厨の相手するなよ
667 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 17:07:11.55 .net] >>652 Cに対するコンプレックス同様 Rubyに対するコンプレックスも見苦しい
668 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/11(日) 22:37:37.82 .net] >>650 returnを省略できる場合に、returnを書くことはないよ
669 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/12(月) 09:24:03.09 .net] 話をぶった切ってすまんが、なるべく依存関係が少ない・かつインタラクティブがある程度機能的なPOSIX互換シェルって何があるかな。 ksh98とかyashとかは使ったことあるけど、ああいう感じでもうちょい開発が盛んなやつとか知らない?
670 名前:名無しさん@お腹いっぱい。 [2018/03/12(月) 17:35:16.53 .net] 連続足し算だけど #!/bin/bash while true do add=expr 0 read x add=$(($add + $x)) echo '----------' echo ' ' $add done でできるが line 5: 0: command not found 1 ---------- 1 ./tasizan-renzoku.bat: line 5: 0: command not found 2 ---------- 3 ./tasizan-renzoku.bat: line 5: 0: command not found と 気色悪い。 どうすれば正解なの?
671 名前:名無しさん@お腹いっぱい。 mailto:sage [2018/03/12(月) 17:39:55.92 .net] expr 0が何も囲われてないが大丈夫か
672 名前:名無しさん@お腹いっぱい。 [2018/03/12(月) 17:48:20.94 .net] すごいね、以下でエラーがなくなった。 #!/bin/bash while true do add=(expr 0) read x add=$(($add + $x)) echo '----------' echo ' ' $add done
673 名前:名無しさん@お腹いっぱい。 [2018/03/12(月) 17:49:39.62 .net] エラーがなくなった が 足し算の合計もなくなった
674 名前:名無しさん@お腹いっぱい。 [2018/03/12(月) 17:58:34.26 .net] a=0 while read x; do a=$((a + x)) echo ---------- echo ' ' $a done
675 名前:名無しさん@お腹いっぱい。 [2018/03/12(月) 18:02:05.44 .net] ありがとう。 合計を外側で定義することがわからなかった。 こうなると