(その1)
echo foo `exec echo bar`
このスクリプトを実行したとき、「foo bar」と出力することを期待したのです
が、FreeBSD 4.6-RELEASEのshは「bar」としか出力しません。「` `」の中がそ
のシェル自身によって実行されているので、execしてしまうようです。bash
2.05, Solaris 8のsh, NetBSD 1.6のsh, OpenBSD 3.1のshはみんな期待通りの振
る舞いをするのですが。
もしやと思って試してみると
: `A=B`; echo $A
も、FreeBSD 4.6-RELEASEのshでは「B」と出力するんですね。
(その2)
for i in x; do
a=foo
done
for i in x; do
a=bar
done 2>/dev/null
echo $a
このスクリプトを実行したとき、「bar」と出力することを期待したのですが、
Solaris 8のshは「foo」と出力してしまいます。ループに 2>/dev/null をつけ
ると、サブシェルで実行されてしまうようです。bash 2.05, FreeBSD 4.6-
RELEASEのsh, NetBSD 1.6のsh, OpenBSD 3.1のshはみんな期待通りの振る舞いを
するのですが。
…で、業を煮やして結局、件のシェルスクリプトはbashスクリプトということ
にしてしまいました。
ni...@ics.nara-wu.ac.jp
bourne系シェルだと、FOO=bar cmd … で、コマンドcmdの実行時の環境変数
FOOを設定することができます。このcmdがシェル関数の場合はどうなるか、とい
うのが、件のシェルスクリプトを書いててはまったもう1つの箇所でした。
試しにこんなスクリプトを書いてみます。
a(){
echo $A
}
b(){
sh -c 'echo $B'
}
A=x; A=y a; echo $A; sh -c 'echo $A'
B=x; B=y b; echo $B; sh -c 'echo $B'
export A; export B
A=x; A=y a; echo $A; sh -c 'echo $A'
B=x; B=y b; echo $B; sh -c 'echo $B'
上から順に y x 空 y x 空 y x x y x x という出力を期待するのですが、実際
にはシェルによって振る舞いはまちまち…
bash 1.14.7, bash 2.05, shとして使った場合のbash 1.14.7
(出力、上から順に) y x 空 y x 空 y x x y x x
shとして使った場合のbash 2.05
(同) y y y y y y y y y y y y
OpenBSD 3.1のsh
(同) y y 空 空 y 空 y y y y y y
FreeBSD 4.6-RELEASEのsh, NetBSD 1.6のsh
(同) y x 空 空 x 空 y x x y x x
Solaris8のsh
(同) x x 空 空 x 空 x x x x x x
さずがにbashは完全に期待通りに振る舞ってくれます。FreeBSDやNetBSDのsh
もそれに近いのですが、上から4番目が期待通りになりません(ここが一番欲しかっ
たのですが)。Solarisのものは、まったく環境変数を渡してくれないですね。逆
にOpenBSDのものは、シェル自身の環境変数まで書き換えてしまうと…
Solaris2.6の/usr/xpg4/bin/sh
y x 空 y x 空 y x x y x x
POSIX的には y x なのかもしれませんが(調べてない)
a(){echo $A}
A=x
A=y a
で y を期待するのは何となく変な感じもします。
#そういうややこしいことするなということですな…
--
kabe
--
ヘ_ヘ ____________________________
ミ・・ ミ vo...@merope.pleiades.or.jp
( ° )~ 日下部陽一
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
In article <180320030146357635%vo...@merope.pleiades.or.jp>, Kusakabe Youichi <vo...@merope.pleiades.or.jp> writes
> 差異といえば、
> cshでalias pu 'pushd \!* | sed -f hoge'
> のようになってた定義って、
> tcshではどうやればいいのでしょうか?
> マニュアルを見ると同じようにできるかのように書いてあるのですが、
> 実際うまくいかないんですよ。(「\!*」の部分が)
僕は出来ている見たい。
tcsh 6.10.00
ですけど。(Mac OS X)
---
Shinji KONO @ Information Engineering, University of the Ryukyus,
PRESTO, Japan Science and Technology Corporation
河野真治 @ 琉球大学工学部情報工学科,
科学技術振興事業団さきがけ研究21(機能と構成)
> うまくいかないんですよ。(「\!*」の部分が)
ぼくもうまくいっているような気がします.
tcsh 6.08.00 です.
> cshでalias pu 'pushd \!* | sed -f hoge'
hogeがなにをするスクリプトか想像がつく気がするのですが,
-v オプションではダメですか. ぼくはこの記事を読んで
2文字にするのはよい案だと思って .cshrc の中の
alias dirs 'dirs -v'
alias pushd 'pushd -v'
alias popd 'popd -v'
を
alias di 'dirs -v'
alias pu 'pushd -v'
alias po 'popd -v'
に変えました.
% pu f
0 ~/f
1 ~/c
2 ~
% po
0 ~/c
1 ~
%
--
love && peace && free_software
西松 毅
In article <yeyd6ko...@cms26.imr.tohoku.ac.jp>, NISHIMATSU Takeshi <t-ni...@imr.edu> writes
> hogeがなにをするスクリプトか想像がつく気がするのですが,
pushd って、もともとスタックを表示しますよね。あれを
見やすくしたいってことなのかな。
> -v オプションではダメですか. ぼくはこの記事を読んで
> 2文字にするのはよい案だと思って
pu/po を10年以上使っているので、su した時にないと結構不便に
感じます。di は、何故か使ってない。
alias pu2 (pu +2)
alias pu3 (pu +3)
alias pu4 (pu +4)
なんかもあるけど、めったに使わないんだけど、たまに使います。
4段にするくらいなら別 kterm を開くな。
alias ZZ exit
は、実はぜんぜん使わない。
最後に cd した所に、飛ぶ hd なんてのもあるな。kterm を渡り歩くとき
に便利。cd `cat .who` とかしているだけですけど。
> pushd って、もともとスタックを表示しますよね。あれを
> 見やすくしたいってことなのかな。
うちは
function cd() {
case $# in
0) set $HOME;;
esac
pushd "$@" > /dev/null
}
です。(bash)
> 最後に cd した所に、飛ぶ hd なんてのもあるな。kterm を渡り歩くとき
> に便利。cd `cat .who` とかしているだけですけど。
同じような感じで + と - というコマンドを作ってます。
+ で保存して、- で戻る。
function +() {
echo $PWD > $HOME/bin/.dir1
}
function -() {
cd `cat $HOME/bin/.dir1`
}
++, --, +++, --- というペアもある。
以前は [[ と ]] という名前だったけど、
bash の新しい内部コマンドとコンフリクトしたので
改名を余儀なくされた :(
神田敏広 <ca...@kgc.co.jp>
In article <b52gc9$sh6$1...@caraway.media.kyoto-u.ac.jp>,
NIDE Naoyuki <ni...@ics.nara-wu.ac.jp> wrote:
> 新出@奈良女子大学でございます。シェルスクリプトを書いてて、環境による
>シェルの振る舞いの差のためにはまってしまいました。くやしいのでちょっと書
>いてみます。
「環境による」という表現は語弊があるのではないでしょうか?
そもそも OS が違えば shell そのものが別物になる訳ですから、
同じ shell が環境に依存して振舞いを変えている訳ではありませ
んよね?
なんか「Mac の Windows」とか「SONY のファミコン」とかいう
素人勘違いと同列の印象を受けてしまいます。そもそも「別物」と
いう認識があれば振舞いが異なっても別に悔しくもないんじゃない
でしょうか。
>このスクリプトを実行したとき、「foo bar」と出力することを期待したのです
>が、FreeBSD 4.6-RELEASEのshは「bar」としか出力しません。「` `」の中がそ
>のシェル自身によって実行されているので、execしてしまうようです。bash
>2.05, Solaris 8のsh, NetBSD 1.6のsh, OpenBSD 3.1のshはみんな期待通りの振
>る舞いをするのですが。
ここに挙げられているのはそれぞれ別の shell ですよね。一般
に /bin/sh として OS に用意されているものは、大きく以下の 5
つに分類されると思います。
Bourne shell: BSD 系 OS、SunOS 系 OS
Korn shell: System V 系 OS、OpenBSD
A shell: NET/2 以降の BSD 系 OS
bash: Linux の多くの distribution
zsh: Darwin
bash と zsh 以外は余り区別して認識されることが少ないような
気がしますが、作者も系譜も違うので、man page に載っていない
ような細部の仕様は異なって当然ではないでしょうか。
# 厳密に言うと Korn shell と PD ksh は違う系譜に属するとは
#思いますけど、Korn shell は POSIX shell 仕様のベースになっ
#ているので、この系統は仕様の揺れが少ないみたいですね。
>このスクリプトを実行したとき、「bar」と出力することを期待したのですが、
>Solaris 8のshは「foo」と出力してしまいます。ループに 2>/dev/null をつけ
>ると、サブシェルで実行されてしまうようです。bash 2.05, FreeBSD 4.6-
>RELEASEのsh, NetBSD 1.6のsh, OpenBSD 3.1のshはみんな期待通りの振る舞いを
>するのですが。
redirect 時に statement 全体を sub shell 化してしまうのは
Bourne shell の特徴です。挙げられているように ash, ksh, bash
にはこの仕様はありません。
Solaris にも ksh が install されていることが多いので、こち
らを使えば「期待通り」の動作を得られるのではないでしょうか。
# jsh は Steve Bourne の手によるものかどうかはともかく、系
#譜としては Bourne shell だと思うので、この辺りの挙動もやは
#り Bourne shell のそれと同じだと思います。
# jsh が出来た頃って Steve Bourne はもう Sun にはいなかっ
#たんでしたっけ?
> …で、業を煮やして結局、件のシェルスクリプトはbashスクリプトということ
>にしてしまいました。
Linux user にはそういう割り切り方をする人が多いようですね。
local に使う分には portability に拘っても無意味なので、動作
環境を固定してしまう方が賢いかも知れません。
# 個人的には「元祖」の Bourne shell 仕様に合わせて書くのが
#正しいような気もしますけど、既に Bourne shell 搭載環境自体
#が希有な存在になってしまいましたから。
--
しらい たかし
> zsh: Darwin
MacOSX ではずいぶん前から bash ですが....
# Public Beta のころは zsh だったかも.
> bash と zsh 以外は余り区別して認識されることが少ないような
> 気がしますが、
げ, そうなんですか?
私は, zsh の振舞にかなり混乱しましたが....
# とくにインタラクティブなところで...