シェルスクリプト総合 その29

■ このスレッドは過去ログ倉庫に格納されています
2018/09/22(土) 11:53:21.38ID:BBiLRgnj0
!extend:on:vvvvv:1000:512
!extend:on:vvvvv:1000:512
シェルスクリプトに関する総合スレッドです。

スレ立て時は以下の文を先頭行に加えて下さい。
後のつけ忘れ防止の為に複数行重ねて追加推奨
!extend:on:vvvvv:1000:512

全般
・荒しは無視しましょう。
・丁寧な姿勢を心掛けましょう。
・ネチケット(死語)を意識しましょう。

前スレ
シェルスクリプト総合 その28
http://mevius.5ch.net/test/read.cgi/tech/1532397676/
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
2018/09/25(火) 05:18:05.28ID:lmrEE7TE0
え,俺?
2018/09/25(火) 05:20:16.93ID:S/r6pG9La
なんか俺は勘違いしたかもしれん、
>>52は無視してくれ
2018/09/25(火) 07:05:22.02ID:BMMTvniR0
>>52
それで恥をかくのは読んでない人なわけで
自業自得だけどな
56デフォルトの名無しさん (ワッチョイ 469f-3QZN)
垢版 |
2018/09/25(火) 08:29:51.94ID:VjhU4mZC0
>>51
今見た。元々リロード忘れて一つ上が見えない状態で書いてたのと、見えた後でリンク先見てなかったのでセキュリティの都合で非推奨になった事に気づかなかった。

でも非推奨ってことは使えないこともないのかな?だからmanページには残ってるとか?使わん方が良いことには変わりはないだろうが。
2018/09/25(火) 09:03:56.75ID:BMMTvniR0
> この方法はセキュリティ上の問題(シフトJISや中国語のエンコーディングではダブルクォーテーションを無効にできてしまうなど。

というような、ASCIIと互換性がない文字コードによる問題だから
そういう文字コード自体を非推奨として対応から外せたら良いのに
Unicode以外の文字コードが絶滅するのはいつになるんだろうな
2018/09/25(火) 22:39:41.88ID:lmrEE7TE0
shebangって書かないほうがいいのかもな。
> If the first line of a file of shell commands starts with the characters "#!",
> the results are unspecified
---http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
だそうだし
> One common historical implementation is that
> the execl(), execv(), execle(), and execve() functions
> return an [ENOEXEC] error for any file not recognizable as executable, including a shell script.
> When the execlp() and execvp() functions encounter such a file,
> they assume the file to be a shell script
> and invoke a known command interpreter to interpret such files.
> This is now required by POSIX.1-2017.
---http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html#tag_16_111_08
だし。
2018/09/26(水) 00:23:55.64ID:+a+RcOTAM
それは誤読だろ。
execveとかにシェルスクリプト渡したらどうなるか知らん、
execlpとか使えってことでしょ。
実装としてどっちで#!を解釈するかはOSに任せられている。
2018/09/26(水) 01:08:43.37ID:yzZF1GUc0
shebangって書かないほうがいいんじゃないかって話は
どこかの誰かがまとめてただろ

書かなくて良いんじゃないかと思うが
書かないとshellcheckが警告出すんだよな。
パラメータじゃない方法でシェルを指定する方法があれば良いんだが
2018/09/26(水) 06:41:40.90ID:aDQj+U850
>>60
> shebangって書かないほうがいいんじゃないかって話はどこかの誰かがまとめてただろ

読んでみたい
2018/09/26(水) 07:00:32.41ID:p8TYnMT50
Google検索ぐらいしたらいいのに
https://myfuturesightforpast.blogspot.com/2017/01/what-is-shebang-binsh-in-posix-shell.html#20170101T1739_Shebang%EF%BC%88#!%EF%BC%89%E3%81%8C%E3%81%82%E3%82%8B%E5%A0%B4%E5%90%88
2018/09/26(水) 07:43:20.75ID:yzZF1GUc0
ったく、そっちじゃねーよ
https://togetter.com/li/1077808

簡単にまとめるとだな。Androidでは sh は /bin/sh に存在しない
/system/bin/sh だから、どちらでも通じるシバンは書けない

なら書かなくて良いのでは?
→ そのとおり。POSIXではシバンがなければshで起動されると明記されてる

(注意 ログインシェルとしてcshを使用してる場合、先頭一文字目が#
つまりコメント行だったらcshで起動されるので:コマンドなどで無効化する
cshはファイルの先頭が#でなければPOSIX shで起動する)
2018/09/26(水) 08:05:31.15ID:p8TYnMT50
ちなみに
bash$ cat ./sbtest.sh
ps -o comm= $$
bash$ ./sbtest.sh
bash
↑↑ Bashじゃねーか
っていう罠もある。
2018/09/26(水) 09:25:36.26ID:pB5sfbMh0
ちょっと質問です。
プログラムが終了していたら再起動し、20秒以上動いていたら強制終了させて再起動したい。
どう書けばいいですか?
66デフォルトの名無しさん (アウアウカー Sae9-rLjT)
垢版 |
2018/09/26(水) 09:56:06.94ID:QtvShas/a
>>65
そうだなあ。Linuxとかならkillでシグナル番号0を送ると指定のプロセスの生死を確認できるのでそれ利用して作るかな。
しかしその場合は動いているプロセスのPIDがわからないとダメだ。これがわからない状態でやらねばならない場合はpsの出力にgrepして探すかな。
2018/09/26(水) 10:01:22.38ID:FJCeOZRMr
> プログラムが終了していたら再起動し、

親シェルスクリプト(プログラム)作ってループ起動
例えばcronの5分間隔とかにすると隙間が開く可能性がある

> 20秒以上動いていたら強制終了させて再起動したい。

監視シェルスクリプト(プログラム)作る
起動させた時間はpsコマンドで分かる
今の時刻はdateコマンドで分かる
強制終了はkillコマンドでできる
監視の間隔(チェックを何分おきにやるか)は自分で決める
例えば1分間隔で監視したら最悪60秒以上動く場合がある

waitしないループは結構CPUに負荷をかけるから注意
2018/09/26(水) 11:15:01.91ID:yzZF1GUc0
こんな感じかねぇ


プログラム名からプロセスIDを取得して変数に入れる
while :; do
 psコマンドでプロセスID変数の起動時間取得
 if 取得できたら; then
  if 20秒以上経過していたら; then
   kill プロセスID
  fi
 else # 取得できなかったら
  プログラム起動 &
  新たなプロセスIDを変数に入れる
 fi
 sleep 1
done
2018/09/26(水) 15:07:59.55ID:yzZF1GUc0
setコマンドで変数一覧が見れる機能の使い道にやっと気づいた

man bashにはこうある

> オプションなしの場合は、シェル変数全ての名前と値の組が表示されます。
> 表示は、現在設定されている変数を設定や再設定をする入力 として
> 再利用できるフォーマットで行われます。

ようは変数のシリアライズとデシリアライズだよなーと思ってた
でもそうだとすると普通は特定の変数のみシリアライズ&デシリアライズしたいわけで
全部だされても困る。指定された変数だけ表示できないのか?
変数の中には改行が含まれることもあるから、絞り込むのも大変だぞ


ちなみになんのために俺がsetを調べていたかと言うと、サブシェルの中から
変数の値を返す方法はないものかと(再度)調べていた。
いわゆるwhile read の中で行数数えても、変数は元に戻る問題な

i=0
cat /etc/hosts | while read line; do
 i=$((i+1))
done
echo $i # whileがサブシェルで実行されるからもとに戻る

この解決方法として、echoでevalできる形の文字列を返してサブシェルの外で
evalするやり方。このテクニックは最近俺の中で常識となっていた。
でもな、setでevalできる文字を返せるのはわかる。だが欲しいのは変数 i だけなんだよ!
set使えねーなって思ってた。

頭が硬かった。setで表示されたものすべてをevalすりゃいいんや。
サブシェルの中の変数は、サブシェルの外を引き継いてるんだから変えない限り同じ。
evalしても変わらない。いちいち必要なものだけechoする必要なかったんや
2018/09/26(水) 15:10:23.80ID:yzZF1GUc0
長文乙w つーわけで、サブシェルの中から変数を返す方法 汎用版

i=0
eval "$(cat /etc/hosts | { while read line; do
 i=$((i+1))
done
set
})"
echo $i # 俺の環境では11だった

set呼ぶだけで、簡単に変数返せるぞ
2018/09/26(水) 15:11:28.48ID:yzZF1GUc0
ちなみにbashとかだとデフォルトでは関数まで返しちゃうので注意な
2018/09/26(水) 22:48:58.32ID:p8TYnMT50
シェルスクリプトじゃないんだけど
Makefileのファイル名(例えばGNUMakefileだったりmakefileだったりするよね)
を取得したりってできる?
つまり
$ cat ./Makefile
all:
>---echo $0
$ make
Makefile
みたいな。もちろんMakefileはshが解釈しないんで, $0を使うことはできないけど。
2018/09/26(水) 23:44:41.88ID:p8TYnMT50
追記
GNU makeなら$(MAKEFILE_LIST)が使えるらしいがFreeBSDでも使いたいんだよね……
2018/09/27(木) 00:12:48.73ID:indBRC1Z0
MAKEFILE_LIST
https://www.freebsd.org/cgi/man.cgi?query=make&;apropos=0&sektion=0&manpath=FreeBSD+6.2-RELEASE&format=html
2018/09/27(木) 00:23:32.14ID:IUmy3t5S0
all:
@echo $(lastword $(MAKEFILE_LIST))

とか。
2018/09/27(木) 00:24:08.12ID:IUmy3t5S0
おっと、TAB が使えないんだったな
2018/09/27(木) 00:36:01.18ID:indBRC1Z0
ああ、>>74はめっちゃ古いのか
.MAKE.MAKEFILES
https://www.freebsd.org/cgi/man.cgi?query=make&;apropos=0&sektion=0&manpath=FreeBSD+11.2-RELEASE&arch=default&format=html
今度は試してみたが確かにっぽい
2018/09/27(木) 02:38:06.19ID:RGPgoULv0
>>70
なんでcatがいるの?
catなくせば苦労しないんじゃないの?
2018/09/27(木) 02:48:37.10ID:Fk1HpByz0
>>78
catはただの一例にすぎん。そこは本質ではない。

サブシェルの中の変数を、サブシェルの呼び出し元に
戻す方法の話をしてる
2018/09/27(木) 03:09:09.89ID:Fk1HpByz0
もう少し見やすく、汎用的な書き方をするとこんな感じかな
サブシェル(change_vars)内で追加や変更した変数を
すべてサブシェルの親に返す方法

# もちろん例
change_vars() { i=123; }
eval "$(somecommand | { change_vars; set; })"
echo $i


実際には変更してないものすべてを再代入してるわけだが
それを行った所で問題はない。

ただしreadonlyを使ってると代入できなくてエラーになる。
これはなにかいい回避策はないだろうか
2018/09/27(木) 03:23:00.68ID:Fk1HpByz0
readonlyになってる変数一覧はreadonly -pで取得できる
その結果をパースしてごにゃごにゃやればできるんだろうけど、

readonly -pの結果が、
bashだと declare -r a="1"
dashだと readonly a='1'
と異なるのでパースが面倒くさい上に、
変数名がわかったからといってどうするのだ?問題がある

サブシェル内でもreadonlyだからunsetできない。
setをパースして消すのは改行文字とかの対応で面倒
エラーを無視しようにもうまくいかない

詰んだw
2018/09/27(木) 03:37:41.74ID:GWQb325r0
"Field with Space" "Second Field" ...
みたいなフィールの連続に対して一番初めのフィールドを取得したいんだけど
なんかいい方法ない? ただしフィールドのなかに特殊な文字は含まれないし、「"」記号もフィールを区別する目的以外には使われてない。
これコマンドに渡す引数の形と似てるから$1とか上手く利用したらいい感じの処理ができそうなんだけど
思い付かん……。
2018/09/27(木) 03:38:09.61ID:GWQb325r0
なぜかフィールドが二箇所でフィールになってるww
2018/09/27(木) 03:50:48.26ID:Fk1HpByz0
ちゃんとフールって書けよw

こんな感じだな

line='"Field with Space" "Second Field"'
echo $line

# 関数呼び出し
foo() {
echo "foo1: $1"
echo "foo2: $2"
}
eval fool $line

# または
eval set -- $line
echo "set1: $1"
echo "set2: $2"

もちろんeval使ってるので、入力データが安全であることが前提
あとは1文字ずつパースして処理するとか
2018/09/27(木) 04:38:59.49ID:GWQb325r0
あーやっぱり変数に代入する感じか。
(データが安全なのは保証されてるんだけど 長いんだよね)
でもありがとう。とりあえずそれで行く。
2018/09/27(木) 04:43:30.53ID:Fk1HpByz0
変数というか、$1, $2, ... だけど
変数($1等含む)に入れないでどうやれとw
標準入力?
2018/09/27(木) 05:30:19.44ID:GWQb325r0
いや 結局変数に入れることと一緒なんだけど
$ echo '"Field with Space" "Second Field"' | { eval set -- "$(cat -)"; echo $1; }
みたいにしてみた。というのは実際のデータは標準出力から流れてくるから
できるだけパイプで処理したいなというのがあった。

いずれにせよeval setなんて思い付きもしなかったんで むちゃくちゃ感謝してる。
難癖を付けてる訳ではないよ。いやマジで。
2018/09/27(木) 07:41:11.09ID:wRik+4En0
>>87
別に気分悪くしたとかじゃなくて、
なにか処理するなら結局変数に入れるよなーってだけだよ
標準入力からでもreadで変数に入れるわけだし

最近eval多用してる。もちろんそれがどうしても必要だからだけど
特に速度が遅くなるわけでもないし色々と便利
2018/09/27(木) 09:31:12.30ID:0Kr1SoI20
丁寧な回答をもらっておいて「でも」「とりあえず」は失礼だろう
「お前の回答はイマイチだが時間もないし採用してやるか」という感じかな?
2018/09/27(木) 09:36:53.29ID:wRik+4En0
今日の荒らしは>>89
2018/09/27(木) 10:20:00.38ID:pwwRK9qRa
荒らし認定兄貴今日もお疲れ様です
2018/09/27(木) 11:06:37.78ID:RGPgoULv0
正論を書くとあらし認定されるんですね
93デフォルトの名無しさん (オッペケ Sr4b-+FqY)
垢版 |
2018/09/27(木) 12:20:46.63ID:99b9Jx0Mr
大体失礼なのはこの手の答えたがりw
94デフォルトの名無しさん (アウアウカー Saab-XaUO)
垢版 |
2018/09/27(木) 13:17:03.86ID:U92lHhY6a
>>70
それ set じゃなくて最後に echo i=$i だけで良いのでは?
2018/09/27(木) 14:01:53.41ID:wRik+4En0
>>94
だから汎用的な解だってばw
変数が複数あっても対応できるし
変数の中にエスケープが必要な文字があっても対応できる

あ、これに関して良いアイデアが浮かんできた。気がするw
2018/09/27(木) 14:05:58.33ID:wRik+4En0
こういう問題について考えていると、bashの拡張ってよく考えられてるなって思うよ
ちゃんと足りなくて必要な機能を追加してくれてる

https://qiita.com/t_nakayama0714/items/80b4c94de43643f4be51#prefix-%E5%A4%89%E6%95%B0%E5%90%8D%E4%B8%80%E8%A6%A7
2018/09/27(木) 17:43:23.75ID:GWQb325r0
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#compact
こういうのとかもすっげえ便利だよね。
$ VAR=val; echo ${VAR@A}
VAR='val'
でも新しい機能なのか,日本語版のマニュアルに掲載されてない。

(まあ俺はPOSIXに準拠したほうがいいと思ってるので,こういう機能は
それこそ一時的な使い捨てスクリプトにしか使わんけど)
98デフォルトの名無しさん (ワッチョイ bf9f-MYrK)
垢版 |
2018/09/28(金) 02:21:47.32ID:5yuIehG00
>>97
それCentOS7に入ってるbashではエラーになる。
新しい機能だな。
2018/09/28(金) 10:45:59.06ID:TLhVFQk50
ファイルのメディアタイプを取得する汎用な方法ってあるかな。
自作してもいいんだけどできれば既存のものを利用したい。
file(1)コマンドの-iオプションがまず思い付いたんだけど,これは
GNU/Linux(http://man7.org/linux/man-pages/man1/file.1.html
FreeBSD(https://www.freebsd.org/cgi/man.cgi?query=file&;sektion=1)
ではメディアタイプで出力するとあるのに対し
本家POSIX(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/file.html
Solaris(https://docs.oracle.com/cd/E26502_01/html/E29030/file-1.html
AIX(https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.cmds2/file.htm
なんかでは特になんの指定もなし……。
メディアタイプなんてド標準なんだから,しっかり規定しておいてほしかったなぁ。
POSIX 2017あたりでさ。
2018/09/28(金) 13:07:01.59ID:bPXaydqo0
>>99
メディアタイプの種類自体は標準化されていたとしても、
あるファイルがどのメディアタイプかってのは決まらないでしょ?

拡張子cgiのスクリプトファイルだって、ソースコード配布サイトなら
テキストファイル扱いにしたいだろうし
2018/09/29(土) 13:10:10.20ID:d3Gl2lPg0
特別な意味をもたせた終了コードをなんにしようかな?って考えてるんだけど
既存で使われてる終了コードとなるべくかぶらせたくない。
どんなのがあるか知らない?

1, 2, 126, 127, 255(bashの予約)
0〜63(fsckで使用)
64〜78(sysexits ユーザー用のうち定義済みのもの)
128〜192(シグナルコードの範囲?)

参考

https://ja.wikipedia.org/wiki/%E7%B5%82%E4%BA%86%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9
https://linuxjm.osdn.jp/html/LDP_man-pages/man7/signal.7.html
https://linuxjm.osdn.jp/html/e2fsprogs/man8/fsck.8.html
http://kaworu.jpn.org/doc/FreeBSD/jman/man3/sysexits.3.php
http://tldp.org/LDP/abs/html/exitcodes.html

一番最後のリンクでsysexitsの作者は64〜113をユーザー用に使うことを提案してるみたいだけど
定義済みを除けば残りは79〜113かな
102デフォルトの名無しさん (ワッチョイ 5780-q1nr)
垢版 |
2018/09/29(土) 13:18:50.90ID:IuTgmxg/0
オツムに欠陥があるヤツでなければ
普通に別の環境変数にいれる
2018/09/29(土) 14:08:42.53ID:PPHj/b7C0
>>101
ていうか寧ろそのなかのどれかでいいんじゃないの?

それともその定義に収まらないエラーなの?
鼻からドラゴンが出ました!exit 80 とか。
2018/09/29(土) 15:12:55.62ID:d3Gl2lPg0
>>103
そう言われるかなとは思ったw

「俺の作ったプログラム」 ==> 「俺の作ったフィルタ」 ==> 「任意のプログラム」

という呼び出しの流れで

「俺の作ったプログラム」 で「任意のプログラム」 の終了コードを知りたいが、
「俺の作ったフィルタ」 独自の終了コードだけは特別扱いしたいということ

「任意のプログラム」のエラーは想定外のエラーで
「俺の作ったフィルタ」のエラーは想定されたエラーで
どちらもエラーではあるんだけど「俺の作ったプログラム」で表示するメッセージが違う
それぐらいなので、かぶってしまっても大きな問題は発生しないんだけどね
2018/09/29(土) 17:52:02.97ID:PPHj/b7C0
>>104
なるほど。
たしかにそういう目的ならば,終了コードが混ざる≠フはよくないな。
しかし例えばapt(1)は非root権限でシステム操作しようとすると
exit 100を返すというトンデモ仕様[Debian 2015]なので,もうどうしようもないんじゃねw
せっかくsysexitに権限異常を示す77があるのにどうして100番を使ってしまったのか……。

[Debian 2015]: https://manpages.debian.org/stretch/apt/apt.8.ja.html#%E8%A8%BA%E6%96%AD%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8
2018/09/29(土) 17:54:32.38ID:PPHj/b7C0
ああ,なんか説明不足で投稿しちゃった。
つまりさ,一応標準で定められたエラー番号はあるものの,
各種アプリケーションが従っている訳でもなく
Debian系のaptコマンドのような超大手のアプリケーションでさえ標準を無視してるんだから,
> 定義済みを除けば残りは79〜113かな
↑こういうのは考えないほうがいいんじゃない? ってこと。
2018/09/29(土) 18:22:23.04ID:d3Gl2lPg0
>>105-106
どこかのなにかにかぶってしまうのは防ぎようがないけど
よく使われるコマンドがこんな終了コードを使っていたっていう事例を知りたいのよ

fsckとかどう見てもエラーじゃねーだろコレっていうのが
エラーあつかいになってて以前はハマったことあるしw

https://linuxjm.osdn.jp/html/e2fsprogs/man8/fsck.8.html
> 1 - ファイルシステムのエラーが修正された
2018/09/29(土) 18:23:25.37ID:d3Gl2lPg0
標準に準拠したいとかそういう話ではなく
単にぶつかりたくないだけ
2018/09/29(土) 18:24:45.45ID:d3Gl2lPg0
> exit 100を返すというトンデモ仕様[Debian 2015]なので,もうどうしようもないんじゃねw

実を言うと今100を使おうとしていたw
やはり裏の裏の裏の裏ぐらいを読まないとダメだなw
2018/09/29(土) 18:40:55.97ID:PPHj/b7C0
非0の返り値だけどコマンドは成功しているっていう例として有名なのはdiff(1)とかかな。
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/diff.html#tag_20_34_14
>1
>  Differences were found.
2018/09/29(土) 18:46:56.62ID:8M0IW2fy0
シグナルでも使ってみたらどうだろうか。
あるいは別にパイプを用意するとか。
112デフォルトの名無しさん (ワッチョイ bf9f-MYrK)
垢版 |
2018/09/30(日) 02:44:50.58ID:KPqVv5wd0
絶対にぶつからないようにするには別の方法でエラーを伝えるようにするぐらいしか方法ないんじゃないか?
同じ値になる可能性のあるものをどちらから発生したかわからない状態で同じ所から得るなんてやはり無理があるだろう。
2018/10/01(月) 01:15:09.47ID:2Ehpmx/A0
こんな書き方できたのか

a=1
case $a in
( 1 ) echo ok
esac
2018/10/01(月) 02:02:45.71ID:IEGoOL+v0
お、おう
2018/10/02(火) 19:23:29.52ID:6qOrAQgQ0
お題

ある関数に対して、apple orange banana ... とN個(Nは任意の個数)の引数を渡した時、
以下のような、引数とその引数のインデックス番号を出力する関数を作成せよ
(単語に対して数値が対応しているわけではない)

apple 1
orange 2
banana 3



ただし、外部コマンド、拡張POSIX機能、変数の使用は禁止とする
(ここでいう変数とはsetコマンドで表示されるもののことである)
2018/10/02(火) 21:27:13.63ID:yoF3UpeG0
>>115
argidx()
{
i=1
for argv in "$@"; do
echo "${argv}" $i
i=$((i+1))
done
}
簡単すぎ
2018/10/02(火) 21:45:46.37ID:yoF3UpeG0
おいこら答えてやったんだからなんとか言えよコラ
エレガントすぎて腰が抜けたか?wwwww

まあ実際,自分で言うのもなんだけどかなり最良に近い方法じゃないかしら。
・POSIX.1-2017準拠
・空白などを含む引数も直感的に指定可能("word with space")
・単純 構造が簡単
・数値の増加にexpr(1)ではなく算術式を利用している為速い
2018/10/02(火) 22:03:54.77ID:kkfm+1S90
変数禁止だから不正解じゃない?
2018/10/02(火) 22:15:20.79ID:xDUI5Isc0
>>115といい、>>117といい変なヤツしかいないやんけ
2018/10/02(火) 23:00:16.05ID:xTxFBCr4a
最初の一個だけならスマートだったのに
褒められたがりが
2018/10/03(水) 00:30:44.79ID:ej0n10jM0
煽りだよ だって明らかに学校の課題かなにかでしょ。
そんなのに真面目に付き合うほど俺は素直じゃない。
2018/10/03(水) 00:44:57.49ID:m57KKa9e0
苦しすぎな言い訳w
2018/10/03(水) 01:48:10.18ID:ej0n10jM0
まあそう思っとけw
124デフォルトの名無しさん (ワッチョイ bf9f-aemA)
垢版 |
2018/10/03(水) 01:59:13.13ID:jikKostS0
>>115
echo は使っては駄目? 拡張されていない sh だと echo はビルトインではなく /usr/bin/echo だと思うが。
2018/10/03(水) 02:01:17.96ID:NkO7phbc0
>>118
そう。変数禁止なので不正解

>>121
変数禁止とか学校の課題ででるわけないじゃないw
2018/10/03(水) 02:03:27.25ID:NkO7phbc0
>>124
使ってOK。
俺の知る限りechoがビルトインでないものは知らない

関係ないけどechoみたいな基本的なコマンドが
シェルによって挙動が違うのはどうにか
ならなかったんだろうか
2018/10/03(水) 02:14:54.02ID:NkO7phbc0
そうか。evalとか外部コマンドは実装不可能なものを除いて
ビルトインで実装することなんて決まりはないのか

では外部コマンドの定義を「現存するシェルでビルトインで実装されたことがないもの」にしよう

オレオレシェル作ってビルトインするのは問題の意図から外れるので、
現存する(誰もが容易に入手可能な)いずれかのシェルで
ビルトインされているならば使って良いものとする
2018/10/03(水) 02:18:56.23ID:NkO7phbc0
あと拡張POSIX機能も使用してOKにしよう。
それを実現する裏技みたいなのがあったら嫌だなと思って入れたが、
もしそれでできるなら俺も勉強になるし。

ようするにPATH環境変数を空にして、どれかのシェルで動けばOKってことだな
条件がグダグダになってしまったw
129デフォルトの名無しさん (アウアウカー Saab-XaUO)
垢版 |
2018/10/03(水) 12:27:47.15ID:61GCF4dla
if や while を外部コマンド動かさずに使うには [ がビルトインのシェルでないとダメだな。
昔の sh は [ が test コマンドへのシンボリックリンクで外部コマンドだったし。
今でもその名残で /bin または /usr/bin に [ が入ってるよな。
2018/10/03(水) 13:43:00.79ID:NkO7phbc0
別件で現在主要のシェルで何がビルトインか調べたことがあるよ

. : [ break cd command continue echo eval exec exit export false kill pwd
read readonly return set shift test times trap true umask unset wait

これらは全てのシェルで使えると言っていいだろう

poshはログインシェルとしては使わないもの扱いなのか
alias bg fg type ulimitが削除されている。(typeないとか地味につらい)
busyboxはgetoptsがないみたい

意外だったのはprintfがビルトインでないシェルがmkshとposhの2つもあったこと。
しかも両方共echoでエスケープシーケンスを解釈してくれるから文字をそのまま出力できない。
mkshの方はset -o posixでエスケープシーケンスを無効にできるしビルトインのprintで代用できるんだが
poshは調べた限りビルトインコマンドでそのまま出力する方法がない
2018/10/03(水) 13:47:38.74ID:m57KKa9e0
いいから、お題の参考答えを出しなさいw
オレオレ定義が曖昧すぎでお題になってないから、もういいでしょ
2018/10/03(水) 13:57:02.54ID:NkO7phbc0
>>131
問題訂正してやるから、もう少し頑張れやw

お題

ある関数に対して、apple orange banana ... とN個(Nは任意の個数)の引数を渡した時、
以下のような、引数とその引数のインデックス番号を出力する関数を作成せよ
(単語に対して数値が対応しているわけではない)

apple 1
orange 2
banana 3



ただし、変数の使用は禁止とし、シェル機能とビルトインコマンドのみを用いること
(ここでいう変数とはsetコマンドで表示されるもののことである)
(使用するコマンドはいずれかのシェルのビルトインコマンドであればよいが、
この問題用に独自シェルを作成するのは禁止とする)
2018/10/03(水) 13:59:49.96ID:m57KKa9e0
なんの目的かさっぱりわからんな。自分でできてんの?っていう疑問からなんだけどなw

>変数の使用は禁止とし
>(ここでいう変数とはsetコマンドで表示されるもののことである)
環境変数のことを言っているのかと思えば違うし、これだけでも曖昧というかオレオレ定義が曖昧だろう
2018/10/03(水) 14:11:05.97ID:NkO7phbc0
>>133
setコマンド実行してみてみばわかるでしょw

setコマンドで表示される変数はシェル変数(環境変数含む)だよ
それを使うのは禁止ってこと
2018/10/03(水) 14:13:32.35ID:NkO7phbc0
今日の24時までに答えが出なければヒント出しますw
2018/10/03(水) 14:16:57.73ID:6m7pNgyW0
そのヒントとやらもグダグダなんでしょw
2018/10/03(水) 14:17:05.40ID:m57KKa9e0
変数を使わない 言語(マシン語すら) は知らんなあ。そういう縛りを設けての目的はなんなん?
やってみたできるけど、クソのようなwにしかならんから、どうか、参考の答えを出してw
2018/10/03(水) 14:19:23.20ID:NkO7phbc0
答えは明日。まあヒントみれば気づく人はすぐわかるでしょう。
コロンブスの卵だよ
2018/10/03(水) 14:20:30.02ID:m57KKa9e0
なんで常時上から目線なのかw コードで語ればいいのに
素晴らしいコードならそんなおれおれ上から目線しなくてもいいくらいなのに。なんかしらんがもったいつけてのまだ「ヒント」とかもったいつけてるしw
2018/10/03(水) 14:21:39.64ID:m57KKa9e0
なんかしらんが見つけて、俺すげーしたいだけっぽいなw
2018/10/03(水) 14:22:11.11ID:NkO7phbc0
> そういう縛りを設けての目的はなんなん?
その理由も答えと一緒に明かします
2018/10/03(水) 14:23:23.18ID:m57KKa9e0
いや、もういらんわw なんかキモすぎて付き合いきれないw
2018/10/03(水) 14:36:43.15ID:ej0n10jM0
多分だけど学校の課題だと予想
根拠は二点:
1. 問題が実利的でない。学校(それもあまり学力の高くない)にありがちな「こんなのできるかな?」系の問題である。
2. 煽ったらそれに乗っかって答えを出してくれる人が思ってるという点で質問者が精神的に幼ない。(高校生くらいか?)
2018/10/03(水) 14:45:22.66ID:m57KKa9e0
posh とかいつもの人でしょ
いつもの人が学校の課題をしなきゃならん人なのか知らんけどw
2018/10/03(水) 15:06:30.08ID:ej0n10jM0
poshなんていうシェルがあるのね。初耳だわ。
2018/10/03(水) 15:10:04.24ID:NkO7phbc0
>>2に書いてあるよ。俺もここ(の何スレか前)で初めて知った
147デフォルトの名無しさん (アウアウカー Saab-XaUO)
垢版 |
2018/10/03(水) 15:58:50.21ID:4kFnpcnsa
$# と shift を使って逆順に値を付加することは簡単にできたんだがな。
2018/10/03(水) 17:25:26.25ID:NkO7phbc0
>>147
俺も第一歩目はそこまでだったw
俺の本来の目的(今回の問題とは別件)は逆順でも実現できたんだけど
なんか悔しかったので、もう一歩進めたら逆にすることなく実現できた
2018/10/03(水) 21:20:26.89ID:SM8JpmZX0
ちょっと前にもこんなグダグダ無かったっけ?
150デフォルトの名無しさん (アウウィフ FFdb-LSDD)
垢版 |
2018/10/03(水) 21:48:53.18ID:Tma5IQlaF
変数使ってはダメって、非合理的でない?
シェルの仕様否定してどーするの?
外部コマンドだって、それがUNIXの設計思想なんだからそれさえも否定するってのも理解不能

ならば、OSそのものを仮想的なものを仮定して
その上で動かすとでもしないと
大昔の情報処理技術者試験用に作られたアセンブラみたいな感じでさ

変数使わない、外部コマンド使用禁止、そんなアルゴリズムが何の役に立つんだろう?
2018/10/03(水) 22:35:14.41ID:ej0n10jM0
でも前はワッチョイやIDがなかったから もっと酷かった。
今はNGすればオッケー☆
2018/10/04(木) 00:37:38.01ID:8ua9ZMtc0
ヒント忘れてたわw

func() {
 *********
 while [ $# -gt 1 ]; do
  *********
  shift
 done
}

func apple orange banana

********の所は1行とは限りません
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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