Fish-shell: &&が機能しない

作成日 2012ĺš´06月19日  Âˇ  98コメント  Âˇ  ソース: fish-shell/fish-shell

cd .. && pwdは、次のエラーを返します。

fish: Expected a command name, got token of type 'Run job in background'. Did you mean 'COMMAND; and COMMAND'? See the help section for the 'and' builtin command by typing 'help and'.
cd .. && pwd

もちろん、 COMMAND; and COMMAND構文を使用できますが、fishがこれをサポートしていると便利です。

ありがとう!

enhancement

最も参考になるコメント

||もいいでしょう。

全てのコメント98件

||もいいでしょう。

別の意見を述べたいと思います。
'||' および「&&」は構文要素であり、「および」および「または」は単純なコマンドです。 このアプローチはシンプルでクリーンです。
既存の機能を実装するために追加の構文要素を導入するのは良い考えではないと思います。
bashとは異なりますが、問題ありません。

&&と||も投票しますこれは一般的に使用されるシンタックスシュガーであり、使いやすさを備えていると非常に便利です。

maxflの提案に+1。

maxflの提案に+1。

Rubyにはandとorキーワードもあります。

+1

誰かがこれを引き受けたいのなら、私は異論はありません。

-1から&& / ||を実装するそして、maxflに+1します。 そして、私はそれが実装されるべき理由を本当に理解していません。 これはシンタックスシュガーではありません。bashでは単なる構文であり、fishではこの構文は存在しません。 また、 ';または'は '||'とまったく同じ数のキーストロークを必要とするため、構文糖衣としては実際には役に立たないでしょう。

and orコマンドと

if begin ; [ a = b ] ; and [ c = d ] ; end
   ...

に比べ

if [ a = b ] && [ c = d ]
    ...

誰かがそれを改善するためのアイデアを持っていますか?

if test a = b -a c = d # or [ ] syntax, but I didn't particularly liked it
    ...

ただし、これはtestビルトインでは機能しますが、他の場所では機能しません。 ビルトインaとbがcとdを実行するためにtrueを返す必要があると仮定しましょう。 そうすれば、そのように書くことができます。

and b
and begin
    c
    d
end

または、ブロック構文とifます。

if begin
        a
        and b
    end
    c
    d
end

または、ネストされた条件を作成します。

if a
    if b
        c
        d
    end
end

繰り返しになりますが、このハックが必要になる頻度はわかりませんが、 searchco.deによると、 &&は主にtest組み込まれている(または副作用のために)使用されています。

fish 、まれに役立つ別の構文が必要かどうかはわかりません。 とにかくバイナリであるため( test )、1つが留まらなければならなかったことを除いて、それはすでに[ように感じます。 特に魚のように感じることはありませんが、バイナリであるため、ここにあります(魚がサポートしていないことを嬉しく思う[[とは異なります)。

構文が2つ(この場合は3つでも)あると、かなり混乱します。 どの構文を使用する必要がありますか?

if a
    b
end
a; and b
a && b

真実の半分を除いて、 &&が最短のようです。 ;andと入力すると、まったく同じ数のキーストロークが必要になります( &はShiftが含まれるため)。 &&を追加すると、構文を追加することをお勧めします( beginようなキーワードを後に挿入できるため、 andは特別な方法で解析され、機能します)。

問題は、 ; andと; or構文があることです。新しい構文は重複しているように感じます。 それらはすでに一種の魔法です( $status変数をチェックするシェルスクリプト関数ではありません)ので、 &&と||置き換えても問題ありません。 || 。

どう考えたらいいのかわからない。 それを行うには、構文が1つだけあるべきだと思います。 私は; andと; orが好きですが、古い構文が削除されれば、 &&と||に問題はありません。 ただし、下位互換性を考慮すると、 ; andと; orを使用したいと思います。 おそらく、 beginが(bashの中括弧のように)短くなるとしたら...しかし、それは怪しげな感じにはなりません。

組み込みの[[をbashのようにサポートしてみませんか? より高速になり(組み込みのエコーを参照)、&&と||をサポートします。 [[および]]内の演算子は、および/または動作をエミュレートします。

[[は実際のコマンドではないため、bashにのみ存在します。 問題は、 [[が[ (ほとんど)と同じであるということですが、不必要な引用を避けるための特別な解析ルールがあります。 直交性の法則と発見可能性の法則を参照して、魚に含まれない理由を確認してください。

実際、 [は、発見可能性の法則と直交性の法則のために存在しないとほぼ確信していますが、 /usr/binのバイナリであるため存在します。 testは、タブ補完を使用して検出できるため、より魚のようです。 ただし、バイナリのブロックはかなり恣意的であるため、組み込みとして実装することもできます。

たとえば、bashでは[[すべての文字列を自動的に引用します。

[[ abc = $variable ]]

しかし、空白の分割動作が存在しないため、魚ではそれは必要ありません。 また、構文機能であるため、 && 、 || 、 < 、および>自動的に引用します。 魚の場合、 &&は-a 、 ||は-oです。 <と>も存在しません。

=~演算子もあります。 fishでは、そのためにquietgrepを使用できます。

echo $ANSWER | grep -qE '^y(es)?$'

また、 bashは<と>演算子があります。 他の文字列よりも大きいまたは小さい文字列をチェックします。 これが役立つことはめったにありません。

また、 =および!=演算子を使用する場合は、正規表現を使用するのと同じように、グロビン構文を使用できます。 繰り返しますが、そのために静かなgrepを使用します。

[[ abc = a* ]]

また、 [[は、 -e 、 -nt 、 -ot 、 -ef 、および!を持つように定義されていますが、魚にはすでにtest組み込まれています。

[[を追加すると、別のキーワードが追加されるだけで、実際には検出できず、実際には多くの機能が追加されません。 唯一の興味深い機能は=~ですが、quiet grep(またはPerl)は、新しい構文を追加しなくても同じことを実行できます。 その上、シェルにすべてを追加するべきではありません。 正規表現を組み込む必要はないと思います。

そうですね、必ずしもbashの[[ビルトインを再実装する必要があるという意味ではなく、独自のプロパティを持つ構文構造として導入する必要があります。 つまり、fishは、bashのように見える多くのキーワードと構成を共有しますが、それらは異なるため、これがどのように行われないかはわかりません。

あなたが言ったことに基づいて、おそらく私たち自身のtestを実装する方が良い構成ですが、魚が代わりにmath実装する方法のように、 condような名前に変更されましたexpr 。 <や>のようなものを実装するところまで行くこともできますが、辞書式順序の代わりに自然な(数値)並べ替えを使用して、文字列だけでなく数字でも機能するようにします。

@Undeterminantビルトイン[[vs
また、bashの[[の精神は、直交性の法則に違反します。これは、構成がサポートする特定の条件に対してのみ、「修正」および/または/またはです。

バッシュのif commands...; then ...; fiが魚やif...then間を簡単に認めるのは皮肉なことです。 しかし、私たちは「その時」を望んでいません。 おそらく、修正するのは、開始...終了を簡単にすることです。

ここに奇妙なアイデアがあります(私はそれが好きかどうかはまったくわかりません):

if (foo; and bar)
  ...
end

現在、コマンド開始時の(...)は違法です。 自然な読み方はこれを実行し、出力をコマンド名として使用することですが、そのためにはeval必要です。
その読み取りを直接許可しないと確信している場合は、裸の(...)をbegin ...; endを意味するように再利用できます。
この位置でstdoutをキャプチャしないことは一貫性がありませんが、非常にコンパクトでクリーンな外観です。

私が嫌いなのは、 if (...)がさらに別の意味を求めていることです。出力をキャプチャして、ブール値の解釈を割り当てます。 例: if (math 2 \< 4) — mathはステータスを返さず、stdoutに0または1を出力します。 重要な用途の1つは、 if $saved_boolです。
これは実用的ではないと思います。特に0/1が絶望的に​​混乱しているため、文字列にブール値の意味を正しく割り当てることはできません。 しかし、最初にif (...)に遭遇したとき、それは合理的な推測のようです。

互換性のために、bashとzshにある一般的な演算子を提供してください。 新規ユーザーが以前のシェル機能のほとんどをコピーして貼り付けるのが簡単になるほど、魚の取り込み率が高くなります。 私は多くの点で魚の方が好きですが、これらのばかげた小さなハードルのいくつかは、15年以上のシェルのカスタマイズを行うときに、実際には問題にならないはずの利点よりも面倒なものになっていることがわかりました。

私は正直に言って、 &&を「ばかげた小さなハードル」とは見ていません。 zshのような「置換シェル」ではなく、魚を独自の言語として扱った場合、学習するのは難しくありません。 魚が最初から最後までどのように機能するかについてのチュートリアルを読んだら、それを理解するのは難しいことではないと思います。

command1; and command2ようなものがあると、 andがcommand2条件付き実行であり、 command1とcommand2間の結合だけではないことがより明確になります。

しかし、 @ Undeterminant 、ほとんどの人が最初にそれを発見したときなどに最初にそれを見るので、あなたはそれを見ていません。その感覚または習熟度のレベルが時間とともに来るようにしてください。 たとえば、古いレガシー構成から数百行を取得しましたが、正直なところ、変換する必要のあるすべてのものをすぐに変換する時間がありません。 私の問題が私の古い設定内のどこにあるかに関して、魚から戻ってくる行番号がないという奇妙なことを見つけています。

あなたの見方は理解できますが、大きなこぶを渡すのではなく、時間をかけて変更を加えたいと考えている人に関しては偏見があります。 誤解しないでください。私が魚を気にせず、入力を試みた場合は、今すぐzshに戻ってください。 このような考え方や推論は、新参者にとってもう少し門戸を開くために重要だと思います。

そうです、あなたは読みやすさについては正しいのですが、古いものを機能させて、人々を引き離すためのエラーではなく警告を与えましょう。

@ylluminateあなたは自分をだましています。 fishが&&をサポートしていても、論理演算子だけでなくスクリプト構文にも多くの違いがあるため、bashまたはzshからの構成を使用することはできません。

その通り。 fishは機能が異なります。つまり、コードを直接コピーして貼り付けるだけではいけません。 コードがbashで記述されている場合は、明示的に魚に変換する必要がない限り、bashとして保持してください。 それらは別々の言語です。

そう
私が行った場合
command1 && command2
魚では、代わりに私がタイプすることを示唆しています
command1; およびcommand2

誰かが(コマンドラインで)2番目のオプションがよりクリーンで未来的で入力しやすいと本当に信じていますか?

新しい構文を導入する代わりに、コマンドを実行するための既存の構文に基づいているため、よりクリーンです。

bashで考えてみましょう:

foo & bar # executes foo in the background, then bar in the foreground
foo && bar # executes foo in the foreground, then executes bar if foo has a zero exit status
foo & bar && baz & qux # left as an exercise for the reader

これは、特別な構文の代わりにコマンドを使用することで避けたい、一種のナンセンスです。

この設計上の決定には、特にifステートメントでコストが発生しますが、これを削減する必要があります。 しかし、「他の貝のように魚を作る方法を見つけよう」ではなく、「その設計哲学の範囲内で魚を改善する方法を見つけよう」という立場からアプローチする必要があります。

あなたのコードは次のことをしますよね(ブロックで&を使用できると仮定して)?

foo &
if bar
    baz
end &
qux

私にとって、それは不自然に思えます。 また、 &構文が非常に紛らわしい場合は、 background組み込みにするなどしてみませんか?

私は実際にそれを行うことを提案していませんが、それは確かに背景を組み込みにするための議論だと思います。

; andと; orは、パイプとの相互作用が不十分なことです。 condition; and echo stuff | grep stuffは機能しませんが、 condition && echo stuff | grep stuffは機能します。 特別な構文を追加する以外に、この問題を回避する方法はありません。

and echo stuff | grep stuffは私にとってはうまくいくようです。 それがどのように壊れているかについて詳しく説明できますか?

@ridiculousfishこれは私が魚を試したときに発見したケースです。 or式はifステートメントの外ではtrueですが、ifステートメントで使用すると(のように見えますか?)falseになります。 私がここで何かを逃していない限り?

root@smogon-dev ~# test 0 = 1; or echo stuff | grep stuff
stuff
root@smogon-dev ~# echo $status
0
root@smogon-dev ~# if test 0 = 1; or echo stuff | grep stuff
                       echo Success
                   else
                       echo Failure
                   end
Failure

bashと比較してください:

~/smogon/bin$ [[ 0 == 1 ]] || echo stuff | grep stuff
stuff
~/smogon/bin$ echo $?
0
~/smogon/bin$ if [[ 0 == 1 ]] || echo stuff | grep stuff; then
> echo Success
> else
> echo Failure
> fi
stuff
Success

この場合:

if test 0 = 1; or echo stuff | grep stuff

次のように記述されていると、より明確になる可能性があります。

if test 0 = 1
    or echo stuff | grep stuff
    ...

orステートメントはif本文にあります! ブール値はコマンドであるため、特別な優先順位はありません。

「括弧」としてbegin / endを使用できます。

if begin; test 0 = 1; or echo stuff | grep stuff ; end
    ...

ですから、それはパイプに関係しているのではなく、優先順位に関係していると思います。

このバグでわかるように、魚がブール演算子をサポートする必要があるかどうかについては多くの意見があります:)

ですから、ここに投入されたエネルギーに感謝します。

私の意図は、どちらが優れているかどうかについての議論をもたらすことではありません。 それはただの実用的なことです。
ほとんどの人と同じように、私には実行する独自のスクリプトがあります。 非常に単純な場合でも、&&条件はコマンドの成功(0を終了)を保証しますが、「;」は何が起こっても気にせずに先に進んでください。 右? したがって、それらはまったく同じではありません。 私たち全員がこれに同意することを願っています。 :)

だから、私は私のスクリプトを持っています、そしてそれらのどれも魚で動作しません。 はい、私はよく使用します&&。 しかし、これは、一般的に&&も使用する、bashを使用したネット上のコードの平和でも発生します。 簡単に言うと、コードを使用できなくなったということです。 :D

私は疑問に思っていました...この動作のみ(&&を意味する)を修正し、従来のbashのように元に戻すために、fish configファイルで関数または定義を確立することは可能ですか? 出来ますか? もっともらしい? 実行可能ですか?

繰り返しになりますが、「and」の使用がより適切で明確になる可能性があることに同意します。 しかし、それは私のコードでは機能しません。また、一般的に、初心者以上のbashコードでは機能しません。 したがって、&&を置き換えるすでに記述されたコードを変更する代わりに(...は発生しません...そしておそらく機能しません)、誰かが必要な場合、または必要な場合に、魚が従来のbashする方が簡単です。

すべての最高の人、そして努力にもう一度感謝します!

bash / zshスクリプトとの互換性について、これまでに完全に近づいたことがありますか? 以前のコメントのとおり、 fishをあきらめました。これは、シェル環境ですでに構築したすべてのインフラストラクチャを、非常に多くのワークステーションとサーバーに変換するために時間をかけるつもりがないためです。 近づいたらもう一度試してみたいです。 そうでなければ、私はそれなしでただ歩き続けるでしょう。 ありがとう。

@rhoconlinux &&をサポートするようにFishを変更しても、bashスクリプトは機能しません。 それよりもはるかに多くの違いがあります。

私はあなたの答えを理解していませんでした^ _ ^
&&問題のエイリアスまたは関数を定義することは可能ですか?

@rhoconlinuxいいえ、Fishパーサーを変更する必要があります(C ++の場合)。 私のポイントは、Fishが&&サポートしていても、FishとBashの間の他のすべての違いのために、Bashスクリプトは実行に失敗するということです。

@kballard痛い! うーん……これを聞いてとても悲しいです。 分かりました。 超クリア。 :)

超高速のフィードバックをありがとう。 私はより良い日常の経験のために魚を使用し、それから私のもののためにbashターミナルを保持します。

乾杯! :+1:

&&が問題になる場合は、簡単に対処できます。

sed 's/&&/; and /' ~/.bashrc > ~/.config/fish/config.fish

しかし、これがあなたがする必要がある唯一のことになることはありそうにありません。 つまり、#522の実装です。

&&互換性の主な動機は、既存のものを変換しないことだと思います
コードベースですが、インターネットからコピーアンドペーストします。
たとえば、 sudo add-apt-repo... && sudo apt-get update && sudo apt-get install ...スニペットが表示され、コピーして貼り付けたいのですが、失敗します。

これは私たちが教育によって解決できるものではありません—常に存在します
貼り付けるスニペット。標準の[ba] sh構文を使用します。
そして、 &&は、私がぶつかっている一番の問題です。
( export FOO=barは#2ですが、 function export; set -x -g (echo $argv | sed 's/=/\n/'); endで解決できます。)

しかし、それは深刻な問題ではありません。私はタイピングの習慣を身につけました。
bash 、貼り付け、Ctrl + D。
うーん、現在/以前を実行するためのキーボードショートカットを追加したいです
bashの下のコマンドライン。

この問題に関する私の2セント:
私はシェルコマンド呼び出しを行うデプロイメントツール(https://github.com/andres-montanez/Magallanes)に取り組んでおり、ユーザーと寄稿者の大多数はbashシェルを使用します。 もちろん、あちこちで「&&」を使用してコマンドを連鎖させます。

明らかな回避策があります(すべてのコマンドを明示的にbashに渡すなど)
しかし、それは多くの問題点をもたらします。 1つは、奇妙な副作用が発生する可能性があることです(つまり、PATHと他の変数が同じように定義されていない)。これは、その唯一の目的のためにツールのコア部分をハッキングすることを意味し、バージョンごとに修正をマージする必要があります。更新するたびに。

&&は、fishと互換性のない多くのbash機能の1つにすぎませんが、最も基本的で広く使用されている機能である可能性があります。 たとえば、上記のツールはPHPであるため、複雑なものはすべてPHPで実行され、基本的なシステムコマンドのみがシェルに渡されます。 このような最小限のユースケースで構文の非互換性を見つけることはイライラします。

私の意見では、 @ cbenが&&と言ったことに完全に同意します。これは、コピーと貼り付けの違いが&&サポートだけである、オンラインのコードスニペットが数百あるためです。
私は同意しますが、構文などの観点から魚がどのように進むかを考慮することが重要です。これは、魚を使用する、または使用したい多くの開発者の生活をはるかに容易にするものだと思います。 &&を; and置き換えるだけのように思えますが、他の人に魚の素晴らしさを伝えると、いつも煩わしくて少しぎこちなく感じますが、いじくり回さなければなりません。いくつかのキーワードを変更すると、彼らは通常、なぜ私がそのような単純なものを変更しなければならないのか疑問に思います。 それから私は魚を守る必要があります、そしてそれは魚を促進するための素晴らしいケースを作りません。
時にはそれは本当に最大の影響を与えることができる最も単純なものです。
つまり、bash &&構文を許可することに全力を注いでいます。

@Globegitterと@cbenが言ったことに同意します。 膨大な量のスクリプトとプログラムが&&と||依存しています。 私はワークステーションでフィッシュシェルを使用していますが、スクリプトを作成するときにシェル間の互換性があると便利です。

FishスクリプトとBashスクリプトの間には、 &&と||以外にも多くの大きな違いがあるので、ここでコメントするすべての人が、Fishに&&を受け入れさせると信じているのはなぜですか。なんらかの意味がありますか? Bashコードのスニペットを実行する必要がある場合は、 bashを実行し、スニペットを実行してから、Fishに戻ります。

多くの人が魚に「転向」したいと思っていると思いますが、それを実現するためのインフラストラクチャがあります。 たとえば、自分のワークステーションだけに15年間のシェルスクリプトがあり(魚を実行したい他のサーバーは言うまでもありません)、変換に時間を費やす必要はありません。 数か月かけて、物事を「魚のように」機能させることは問題ありませんが、別のシェルに変更するためのワークフローにそのような初期投資を行う方法はありません。

一般的な互換性の問題に対処すれば、魚にはかなりのユーザーが流入すると思いますが、魚の開発に携わる他の人が言っていることから、これはプロジェクトの優先事項ではないようです。 この点で風景が変わったら、最終的には魚に移りたいので、私はこの理由からこれに目を光らせています。

必要に応じてbashまたはzshを実行することに関しては、私の場合、これらのシェルを実行するのはかなりの量になります。それ以外の場合は、このパスをたどるのはばかげています。

@kballard私はfishで行うスクリプトの95%に理想的なワークフローを持っています:cmd + C別のソースからの非常に単純なスクリプト、cmd + tabからiTerm、cmd + v、Enter。 それが私がやりたいことのすべてであり、余分なbashなどは何もありません。 ほとんどの場合、これらのスクリプトがこの正確なワークフローで機能するのを妨げる唯一のことは、 &&存在することです。 それが私と私にとって、この問題を解決する他のほとんどの人が非常に役立つと思う理由です。
あなた自身がそれを経験していないのなら、あなたのワークフローが頻繁に中断された場合、それは合計され、本当にあなたの心に固執すると私を信じてください。

私は他のすべてのために魚が大好きで、それが私が元に戻すことができなかった理由です、しかしこの単純なことはそれが私にとって素晴らしいことを妨げるものです、そして私はここで他のいくつかを仮定します。

どうぞ。 PR#1633が着陸したら、次のものを取得して~/.config/fish/functions/fish_user_key_bindings.fish保存できます。

function handle_input_bash_conditional --description 'Function used for binding to replace && and ||'
    # This function is expected to be called with a single argument of either & or |
    # The argument indicates which key was pressed to invoke this function
    if begin; commandline --search-mode; or commandline --paging-mode; end
        # search or paging mode; use normal behavior
        commandline -i $argv[1]
        return
    end
    # is our cursor positioned after a '&'/'|'?
    switch (commandline -c)[-1]
    case \*$argv[1]
        # experimentally, `commandline -t` only prints string-type tokens,
        # so it prints nothing for the background operator. We need -c as well
        # so if the cursor is after & in `&wat` it doesn't print "wat".
        if test -z (commandline -c -t)[-1]
            # Ideally we'd just emit a backspace and then insert the text
            # but injected readline functions run after any commandline modifications.
            # So instead we have to build the new commandline
            #
            # NB: We could really use some string manipulation operators and some basic math support.
            # The `math` function is actually a wrawpper around `bc` which is kind of terrible.
            # Instead we're going to use `expr`, which is a bit lighter-weight.

            # get the cursor position
            set -l count (commandline -C)
            # calculate count-1 and count+1 to give to `cut`
            set -l prefix (expr $count - 1)
            set -l suffix (expr $count + 1)
            # cut doesn't like 1-0 so we need to special-case that
            set -l cutlist 1-$prefix,$suffix-
            if test "$prefix" = 0
                set cutlist $suffix-
            end
            commandline (commandline | cut -c $cutlist)
            commandline -C $prefix
            if test $argv[1] = '&'
                commandline -i '; and '
            else
                commandline -i '; or '
            end
            return
        end
    end
    # no special behavior, insert the character
    commandline -i $argv[1]
end

function fish_user_key_bindings
    bind \& 'handle_input_bash_conditional \&'
    bind \| 'handle_input_bash_conditional \|'
end

これにより、 &と|バインドされ、 & &&または||と入力すると、適切な; and / ; or自動的に変換されます。 command one && command two形式の行に貼り付けて、機能させることができます。

PR#1633が受け入れられるまで、このスクリプトは_typing_ && / ||が、貼り付けでは機能しないことに注意してください。

@kballardうわー、それは素晴らしいニュースです! どうもありがとう。

これは実際には検索モードを適切に処理していないように見えます(ページャーモードについてはよくわかりません。正確に何が構成されているのかわかりません)。 検索中に&または|を押すと、検索が終了します。 そうは言っても、どうやってそれを処理するのかわかりません。

複数行のコマンドで|または&と入力するためのバグ修正を使用して、スクリプトを更新しました。

@kballardPRが上陸したのを見ました。 したがって、上に貼り付けたスクリプトは、 &&を最新のマスターで機能させる必要がありますか?

ええ、そうすべきです。 試してみて、問題があれば教えてください。

-ケビン

2014ĺš´9月1日には、午前1時14分AMで、マルクスPadourek [email protected]書きました:

@kballardPRが上陸したのを見ました。 それで、上に貼り付けたスクリプトは、最新のマスターで&&を動作させる必要がありますか?

—
このメールに直接返信するか、GitHubで表示してください。

数日前にリリースされた新しい2.1.1バージョンでこのスクリプトを試しましたが、機能していないようです。 2.2まで待たなければなりませんか? ありがとう!

@pragmattica :2.1.1はセキュリティバグ修正リリースでした。 新しい機能は追加されませんでした。

@xfix :

素晴らしい:+1:

実行中の変更ログはありますか? ルートCHANGELOGはかなり古くなっているようです。

@pragmattica魚2.2が出たので、ubuntu 14.04で試してみましたが、 echo 'test1' && echo 'test2';がecho test1 &; and echo 'test2';変わります

fish_user_key_bindings.fish内のどこかに問題がありますか? (私はそれを自分で調べようとしますが、私の魚/バッシュスクリプトの知識は少し不安定です)

編集:ただし、 &&してコマンドを入力すると機能するようです。 後でそのスペースで起こるとしたら少しいいかもしれませんが、それはそれほど重要ではありません。 その半分が機能しているのは素晴らしいです:)

-1から奇妙な記号:

if [[ a = b ]]; and [[ b = a ]]; or [[ c = b ]]; then echo hello; and echo world; done

単純なシンボルへの+1:

if [[ a = b ]] && [[ b = a ]] || [[ c = b ]]; then echo hello && echo world; done

ああ、問題が@pragmatticaであることがわかっていると思います。コマンドcommandlineは、引用符なしでバッファーを返します。 うん、そうだね。 したがって、 https://github.com/fish-shell/fish-shell/issues/2210が修正されたら、上記のスクリプトも修正する必要があります。

これはまだ検討され始めていますか?

+1
シンボルは奇妙なものではなく、多くのプログラミング言語のロジックに一般的に使用されています。
コピーアンドペーストの互換性は非常に現実的な議論であり、私はそれを支持しています。

私は悪者になり、この議論を締めくくります。 これは実装されません。 特に、「bashスクリプトからコマンドをカットアンドペースト」できるようにしたいという繰り返しの発言に悩まされています。 fishが&&および||演算子をサポートしている場合でも、これらの演算子を含むステートメントを単純に切り取って貼り付けることができるとは限りません。 私たちはあなたがそうすることができるという印象を与えたくありません。 正直なところ、bash / zshの構文と動作が必要な場合は、それらのシェル(またはそれらとの互換性を主張する代替手段)を使用する必要があります。

議論された他のアイデアのほとんどは、独自の問題を抱えているはずです。 特に、ksh88(bashではない)によって最初に導入された[[ ... ]]動作のいくつかを実装することにはいくつかのメリットがあるかもしれません。 しかし、おそらく、これらの特別なトークンを実装するのではなく、組み込みのtestコマンドまたは新しいコマンドを拡張することによって。

zshとbashをサポートしないというこの概念にはまだ非常に不安があります。 論理は理解できますが、同意しません。 昔は魚にとても興味がありましたが、反対で引っ越しました。 開発者として、これが実装されることを望んでいる私たちが十分にいる場合は、ここでプロジェクトをフォークする機会があるかもしれません。 このような興味深い作品の前進の勢いと受け入れを最終的に妨げるこの継続的な抵抗を見るのは悲しいことです。

@ylluminate 「zshとbashをサポートする」ことで何を考えていますか? どのレベルの互換性が必要ですか?

zshとbashをサポートしないというこの概念にはまだ非常に不安があります。 論理が理解できます...

魚がbashとzshの機能をサポートするためのロジックがわかりません。 Javaが必要な場合、なぜC ++を使用するのですか? Perlが必要な場合、なぜPythonを使用するのですか? @ridiculousfishがちょうど尋ねたように、いくつかの構文糖衣の他に、魚があなたを幸せにするために他に何をサポートしなければならないでしょうか? 魚はどの時点で別のバッシュクローンになりますか?

PS、私は1979年から生計を立てるためにプログラミングをしており、80年代半ばからUNIXを使用しています。 数え切れないほど多くのシェルを使用しました(例:Bourne、Csh、Ksh88、Ksh93、Bash、Zsh、Xonsh)。 シェルの切り替えには常に作業が必要です(そのため、5年に1回程度しか切り替えません)。 そうするとき、新しいシェルが変更なしにすべてのレガシースクリプトを実行しないと文句を言うことはありません。

@ krader1961いいスピーチ。 私の謙虚な意見では...

私はいつも魚のスクリプトを書くわけではありません(注文が続きます):

  1. 魚のスクリプトは遅い(mkshより遅い)
  2. いくつかの奇妙な構文(例: ; and 、 ; or 、私には醜いように見えます)
  3. posix互換ではありません(構文は簡単ですが、それでも学習する時間が必要です)

ええと、魚のスクリプトが他のシェル(mksh、bashなど)

一方、私は魚を使用します。理由は次のとおりです。

  1. 起動時間はzshよりも速い(ただしbashよりは遅い)
  2. デフォルトで多くの機能が有効になっています(構文のハイライトが最適です)
  3. 構成は素晴らしくシンプルです(特にset -Ux )

@ylluminateこの4年前の号を見ると、bashのような魚を楽しみたい人がまだ怠惰で忙しいことがわかります。 熱心な人たちは自分の殻を作っています(マジシャン/ヤッシュ、エルフ/エルフ、マイケルマシニス/ああ、そして私:-Pなど)。 魚のような方法で物事をやりたいのなら、おそらく魚のない殻が必要です。

&& ||を魚に実装する方法を本当に検討し、それをそれほど魚っぽくないものにしない場合は、 begin; endを排出していることがわかります(コミット594b460ba2d8dca59a3bfd282397c5f33aa9da6fが行うことを参照してください。カウンター- ; and orは二重の役割を果たし、とてもやや醜い)そしてほんの少しの砂糖を手に入れます。

@pickfire 「魚の台本が遅い」について詳しく

私のテストの魚でFWIWはのおかげで、より高速な全体的なbashのよりposix_spawnそれはのような特定の場合には遅くなるかもしれませんが、その高速なパーサalias 。

ivan<strong i="5">@alarmpi</strong> /tmp> echo 'echo test' > script
ivan<strong i="6">@alarmpi</strong> /tmp> time bash script
test
0.02user 0.01system 0:00.03elapsed 96%CPU (0avgtext+0avgdata 2776maxresident)k
0inputs+0outputs (0major+149minor)pagefaults 0swaps
ivan<strong i="7">@alarmpi</strong> /tmp> time mksh script
test
0.00user 0.00system 0:00.02elapsed 0%CPU (0avgtext+0avgdata 1420maxresident)k
480inputs+0outputs (2major+82minor)pagefaults 0swaps
ivan<strong i="8">@alarmpi</strong> /tmp> time fish script
test
0.07user 0.01system 0:00.09elapsed 85%CPU (0avgtext+0avgdata 4204maxresident)k
352inputs+0outputs (2major+231minor)pagefaults 0swaps

@ridiculousfish echoつぎ

@ krader1961 @ridiculousfish IMO、 https://github.com/fish-shell/fish-shell/issues/2210がリリースされると、これを閉じることができます。 @kballardが投稿した非常に簡単な解決策があります。

@pickfireそれを共有してくれてありがとう。 このテストは、 echo時間ではなく、起動時のオーバーヘッドを測定しています。 起動時間は非常に重要ですが、そのテストから起動時間(主にconfig.fishに依存します)を超えて結論を出すことはできません。

別のマイクロベンチマークは次のとおりです。

> cat test.fish
for i in (seq 1000)
    ls > /dev/null
end

> time fish test.fish
        1.51 real         0.74 user         0.65 sys

> cat test.sh
for i in {1..1000} ; do
    ls > /dev/null
done

> time bash test.sh
        2.01 real         0.85 user         1.12 sys

ここでは魚がたくさん勝ちますが、これは主にフォークとposix_spawnの違いを測定しています。

ここでの結論の1つは、包括的なベンチマークスイートが必要だということです。

@ridiculousfishこれが、あなたが私にくれたベンチマークです。

> cat test.fish
for i in (seq 1000)
    ls > /dev/null
end
> time fish test.fish
4.18user 4.04system 0:22.62elapsed 36%CPU (0avgtext+0avgdata 4360maxresident)k
96inputs+0outputs (1major+321041minor)pagefaults 0swaps
> cat test.sh
for i in {1..1000} ; do
    ls > /dev/null
done
> time bash test.sh
0.70user 1.62system 0:09.81elapsed 23%CPU (0avgtext+0avgdata 2844maxresident)k
0inputs+0outputs (0major+154100minor)pagefaults 0swaps
> time mksh test.sh
0.00user 0.01system 0:00.04elapsed 24%CPU (0avgtext+0avgdata 1780maxresident)k
752inputs+0outputs (3major+203minor)pagefaults 0swaps

mkshは印象的なスピードを持っているようです。

@pickfire fishのlsは、Linux上の関数であり、bashが実行していない、出力をより適切にするために他の処理を実行します。 Linuxでリンゴとリンゴを比較したい場合は、 command ls 。 (ダーウィンでは、魚のlsラッパーははるかに薄いです-私はそれを指摘する必要がありましたが、私は忘れました。)

テストでのmkshの「印象的な速度」の説明は、mkshにはブレース拡張がないため、 ls 1回だけ呼び出すことです。 明らかに、 ls 1回呼び出す方が、1000回呼び出すよりもはるかに高速です。

これは、パフォーマンス測定が非常にトリッキーであることを示しています。測定していると思うものとは異なるものを測定するのは非常に簡単です。

@ridiculousfish 、 ls関数を使用する理由はありますか? command lsと比較して魚のスクリプトですか? スクリプト作成中の出力は重要ではありません。

さて、今回はあなたが言ったことをしました:

> cat test.fish
for i in (seq 1000)
    command ls > /dev/null
end
> time fish test.fish
0.66user 1.04system 0:08.08elapsed 21%CPU (0avgtext+0avgdata 4364maxresident)k
624inputs+0outputs (4major+113176minor)pagefaults 0swaps
> cat test.sh
for i in $(seq 1000) ; do
    ls > /dev/null
done
> time mksh test.sh
0.21user 0.65system 0:07.64elapsed 11%CPU (0avgtext+0avgdata 1884maxresident)k
0inputs+0outputs (0major+119632minor)pagefaults 0swaps
> time bash test.sh
0.15user 1.04system 0:08.66elapsed 13%CPU (0avgtext+0avgdata 2816maxresident)k
0inputs+0outputs (0major+150700minor)pagefaults 0swaps

最後に、 mkshは依然として最速ですが、 fishがmkshよりも速いのは印象的です。 fishに並列コマンド実行サポートが組み込まれていれば、それがすべての中で最速だったと思います。

その.66ユーザー時間はかなり長いです。 config.fishのコンテンツ(エイリアスの定義など)が原因だと思います。 ちなみに、これは私のLinuxボックスに表示されるものです(それぞれ3つのうちで最適です)。

> time fish test.fish
0.15user 1.21system 0:01.33elapsed...
> time mksh test.mksh
0.12user 1.13system 0:01.24elapsed...
> time bash test.sh
0.18user 1.34system 0:01.47elapsed...

誰もがとても近いです。

ベンチマークにとって、fork / execまたはposix_spawnをパスコマンドに実行する一種の「オラクルシェル」を組み込むことは興味深いかもしれません。これにより、OSが提供できる最大速度からどれだけ離れているかを知ることができます。 。

@ridiculousfish 、私のconfig.fishは非常に短いです:

# Solarized colors
test $SHLVL = 2
and sh $HOME/.config/base16-shell/base16-solarized.dark.sh &
set fisher_home ~/.local/share/fisherman
set fisher_config ~/.config/fisherman
source $fisher_home/config.fish

おそらくfisherman使用しているので、速度が低下するかどうかはわかりません。 @bucaranはこのためのいい人です。 今回は、 config.fishを空にしました(5回の再試行の最良の結果):

> time fish test.fish; time mksh test.sh; time bash test.sh
0.62user 1.09system 0:07.28elapsed 23%CPU (0avgtext+0avgdata 4396maxresident)k
0inputs+0outputs (0major+108240minor)pagefaults 0swaps
0.21user 0.62system 0:06.92elapsed 11%CPU (0avgtext+0avgdata 1888maxresident)k
0inputs+0outputs (0major+116674minor)pagefaults 0swaps
0.29user 0.81system 0:07.78elapsed 14%CPU (0avgtext+0avgdata 2780maxresident)k
0inputs+0outputs (0major+145628minor)pagefaults 0swaps

@ridiculousfish @pickfireメッセージをブロックできるように、別の問題でチャットできますか?

はい、この問題をスパムして申し訳ありません。 @pickfire特に興味深い、または関連性があると思われるベンチマークをフォローアップしたい場合は、別の問題を開いてください。

bashとzshの互換性については、個人的には完全な互換性は期待していませんが、互換性を少しでも追加することで、魚の人気が高まる可能性があります。
スクリプトを考慮しなくても、 &&と||はコマンドの連鎖に非常に一般的に使用されるため、重要です。 例として、私はまだ#2292に問題があります。 魚のバグではないと考えられることは知っていますが、魚の相性を改善することで修正できるのは事実です。

私はここでmaxflを使用しています:-1:これが人気投票であると思われる場合、魚の構文の一部として||と&&を持っているため。

魚はbash(またはzsh)ではありません。 &&と||を実装する理由は、これらのシェルとの互換性以外にありません。 現状との互換性は、このプロジェクトの反目標です。

@Nodd :問題#2292への参照は、実際には、fishがその構文を実装してはならない理由の例です。 そうすることは、魚がPOSIX(bash、zshなど)のクローンであると人々に思わせるためのもう1つのステップになります。 それは、魚が他の地域の貝殻のように振る舞うという他の要求を生み出すだけです。

解決策を探しているすべての人にとって、fish 2.3以降、最終的に完全に機能する解決策があることを確認できます。

上記の回答に記載されていることを実行してください。

どうぞ。 PR#1633がリリースされたら、次の情報を取得して〜/ .config / fish / features /fish_user_key_bindings.fishに保存できます。

function handle_input_bash_conditional --description 'Function used for binding to replace && and ||'
    # This function is expected to be called with a single argument of either & or |
    # The argument indicates which key was pressed to invoke this function
    if begin; commandline --search-mode; or commandline --paging-mode; end
        # search or paging mode; use normal behavior
        commandline -i $argv[1]
        return
    end
    # is our cursor positioned after a '&'/'|'?
    switch (commandline -c)[-1]
    case \*$argv[1]
        # experimentally, `commandline -t` only prints string-type tokens,
        # so it prints nothing for the background operator. We need -c as well
        # so if the cursor is after & in `&wat` it doesn't print "wat".
        if test -z (commandline -c -t)[-1]
            # Ideally we'd just emit a backspace and then insert the text
            # but injected readline functions run after any commandline modifications.
            # So instead we have to build the new commandline
            #
            # NB: We could really use some string manipulation operators and some basic math support.
            # The `math` function is actually a wrawpper around `bc` which is kind of terrible.
            # Instead we're going to use `expr`, which is a bit lighter-weight.

            # get the cursor position
            set -l count (commandline -C)
            # calculate count-1 and count+1 to give to `cut`
            set -l prefix (expr $count - 1)
            set -l suffix (expr $count + 1)
            # cut doesn't like 1-0 so we need to special-case that
            set -l cutlist 1-$prefix,$suffix-
            if test "$prefix" = 0
                set cutlist $suffix-
            end
            commandline (commandline | cut -c $cutlist)
            commandline -C $prefix
            if test $argv[1] = '&'
                commandline -i '; and '
            else
                commandline -i '; or '
            end
            return
        end
    end
    # no special behavior, insert the character
    commandline -i $argv[1]
end

function fish_user_key_bindings
    bind \& 'handle_input_bash_conditional \&'
    bind \| 'handle_input_bash_conditional \|'
end

@Globegitter

どうですか?

function sudo_bang_bang --on-event fish_postexec
    abbr !! sudo $argv[1]
end

@brjまたそれを~/.config/fish/functions/fish_user_key_bindings.fishますか? それは私にとってはうまくいかなかったようです。

この関数を調達する必要があります。 したがって、オプションはそれをconfig.fishに配置するか、〜/ .conf.d / [name-dont-matter] .fish内に配置することです。

@brj :その関数の問題が間違っています。 これは「!!」ではなく「&&」と「||」についてです - 異なるもの。

@faho lol、あなたは正しいです。 その問題からいつも通知が届くので、これもsudoの別のケースだと思いました!!。

@Globegitter混乱してすみません!

ユーザーが便利にコピーできるように、提案された回避策を魚を例として出荷するのはどうですか? エラーメッセージは、これに言及するために簡単に拡張できます。 ほぼすべてのシェル(unix-yシェル以外のWindows cmd.exeを含む)で動作するため、&&が使用されている同じ1つのライナー(gerrit code-reviewから)を貼り付け続けます。 私にとって、上記のスクリプトは生産性を向上させるものです(しばらくの間、bash -c "p​​aste here"と入力していました...)。

私はどのように行いますか && ? 解決策はありますか?

上記と同じ問題、私は本当にする方法を見つけることができません

gcc test2.c -o a.out && ./a.out

魚で。

gcc test2.c -o a.out; and ./a.out

@ivanはそれを試しましたが、gccの引数として「and」と「./a.out」を指定します。

//編集:ちなみに、これは魚では完全に不可能であるように思われるため、bashスクリプトを使用することになりました:(

gcc test2.c -lwlc -o a.out && (( sleep 2s; DISPLAY=:2 xterm ) & ./a.out)

私はこの「完全に不可能な」ことを頻繁に行います。 きれいな魚の環境で; and構文を試してみませんか? うまくいかない場合は、セミコロンに何か問題がありますか? これを魚に入力していますか、それとも別のプログラムから渡されていますか?

@ivanで入力します。

おそらくばかげた質問で申し訳ありませんが、かっこはどうすればよいですか? ドキュメントでそれらについての単語を見つけることができず、それは正確にグーグル可能なトピックではありません:(

gcc test2.c -lwlc -o a.out &&((sleep 2s; DISPLAY =:2 xterm)&。/ a.out)

@kozecここでアイテムをグループ化するのに問題があると思います。 使用する必要があるのは、左ブレースのようなbegin (私はそれを考える方法です)と右ブレースのようなendです。

gcc test2.c -lwlc -o a.out; and begin sleep 2s; env DISPLAY=:2 xterm; end & ./a.out

またはインデント:

      gcc test2.c -lwlc -o a.out
         and begin sleep 2s
             env DISPLAY=:2 xterm
         end & ./a.out

@floamありがとう、それはほとんど機能します。 しかし、&の前のものはバックグラウンドに送信されません:(

最小限の例:

begin sleep 2s ; env DISPLAY=:2 xterm ; end & Xephyr :2

2秒間スリープしてから、xtermを起動し、_then_はそのxtermのXServerを起動します。 XServerの準備が整う前にxtermofcがクラッシュします。

ああ、ごめんなさい。 問題: https :

あなたはあなたがきれいではなく、あなたがしなければならないこれによってあなたがそれを回避することができるのを見つけるでしょう:

fish -c 'sleep 2s; env DISPLAY=:2 xterm' & Xephyr :2

npm run-scriptsの開発、構築、および内部で既存のスクリプトが大量にある場合、特に一部/ほとんどが魚ではないため、切り替えるのは合理的ではありません。 シバンを使用した通常のbashスクリプトの場合、もちろん問題はありません。

&&の優れた(または「優れた」)点は、LinuxやMacだけでなく、開発環境などの迅速なセットアップに適したWindowsの通常のシェルでも機能することです。

決して取引を妨げるものではありませんが、なぜそれを追加するのか理解するのは難しいですか?

まあ、これはかなりばかげた議論です。 魚のコンパイラに異なる「モード」を持たせてみませんか? つまり、「純粋な」魚のものを使用したり、魚のイズムと一緒にバッシュのようなシェルと互換性を持たせたりできる、有効にできるある種の設定です。 他のシェルとは異なる「レベル」の互換性を持たせることで、完全な互換性、互換性のないもの、またはその間の何かを実現することもできます。 つまり、基本的なレベルでは、少なくともこのために何らかのソース間コンパイラを実装できます。 または、bashコードを取得して、魚の内部中間表現に変換します。 この点で、あなたは翻訳のためにあらゆる種類のことをすることができます。 私が間違っている場合は訂正してください。ただし、bash etal。の言語レベルの概念は信じています。 魚と魚は世界的に驚くほど違いはありませんよね?

とにかく、それはこの問題に関する私の0.02ドルです。これは、次の前提に基づいて構築されているため、本当にばかげているように見えます。

"pure fish"
XOR
"compatibility with bash / becoming another bash clone"

これらの2つの概念の間に中間点があることを妨げるものが何もないとき。

少なくとも、bashのようなシェルは、魚などのより難解なシェルよりもはるかに標準的で人気があるという現実に直面する必要があります。したがって、魚がつま先に立つことができるシェルになる現実的な可能性のために、何らかの互換性レイヤーが実際に存在する必要があります。 -広く普及していて互換性の問題を引き起こさないという点で、bashを使用してつま先まで。

...これらの2つの概念の間に中間点があることを妨げるものが何もないとき。

必要なコードを書くために2,000時間(1人年)以上を投資している人(または人々のグループ)以外の何者でもありません。 そのすべてを実装するために、 @ ylluminariousのプルリクエストを確認することを楽しみにしています。 あなたが提案していることは、なぜ誰かがPythonにPHPを解釈させることができないのかを尋ねることと同じです。 答えは、理論的には互換性スイッチを使用できるということですが、なぜそうするのでしょうか。

#4620で実装されました。

このページは役に立ちましたか?
0 / 5 - 0 評価