Fish-shell: && не работает

Созданный на 19 июн. 2012  ·  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, но это нормально.

Я бы также проголосовал за наличие && и || поскольку это обычно используемый синтаксический сахар, и было бы неплохо иметь его с точки зрения удобства использования.

+1 к предложению maxfl.

+1 к предложению maxfl.

В Ruby также есть ключевые слова and и or .

+1

Я не возражаю, если кто-то захочет этим заняться.

-1 к реализации && / || и +1 к maxfl. И я действительно не вижу причин, по которым это должно быть реализовано. Это не синтаксический сахар, в bash это просто синтаксис, а в fish этого синтаксиса не существует. Это также было бы действительно бесполезно в качестве синтаксического сахара, как '; or', требует ровно столько же нажатий клавиш, сколько '||'.

Мне нравится простота команд and и or , но одна проблема в том, что они делают операторы if странными. Например:

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 должны возвращать значение true для запуска c и d . Тогда мы могли бы написать это вот так.

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 ). Это не кажется особенно подозрительным, но оно здесь, потому что оно двоичное (в отличие от [[ которое, я рад, что Fish не поддерживает).

Наличие двух синтаксисов (а в данном случае даже трех) может сбить с толку. Какой синтаксис мне использовать?

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

Похоже, что && самый короткий, но это половина истины. Ввод ;and требует точно такого же количества нажатий клавиш (потому что & включает Shift). Добавление && будет стимулировать добавление дополнительного синтаксиса (опять же, and анализируется особым образом, потому что вы можете вставить после него ключевые слова, такие как begin , и они работают).

Проблема в том, что у нас есть синтаксисы ; and и ; or - новые синтаксисы будут казаться дубликатами. Они уже в некотором роде волшебные (это не просто функция сценария оболочки, которая проверяет переменную $status ), поэтому у меня не было бы проблем, если бы они были заменены на && и || .

Я не знаю, что и думать. Я думаю, для этого должен быть только один синтаксис. Мне нравятся ; and и ; or , но у меня не было бы проблем с && и || , если бы старые синтаксисы были удалены. Но, учитывая обратную совместимость, я бы предпочел остаться с ; and и ; or . Возможно, если бы begin было бы короче (как фигурные скобки в bash) ... но это не выглядело бы подозрительно.

Почему бы не поддерживать встроенный [[как это делает bash? Это было бы быстрее (см .: встроенное эхо) и поддерживало бы && и || операторы внутри [[и]] для имитации поведения и / или.

Поскольку [[ не является реальной командой, она существует только в bash. Проблема в том, что [[ аналогичен [ (в основном), за исключением того, что у него есть специальные правила синтаксического анализа, чтобы избежать ненужного цитирования. Посмотрите на закон ортогональности и закон видимости, чтобы понять, почему этого нет в рыбе.

Фактически, я почти уверен, что [ не существовало бы из-за закона обнаруживаемости и закона ортогональности, но это так, потому что оно двоично в /usr/bin . test более подозрительный, потому что вы можете обнаружить его, используя завершение табуляции. Но блокирование двоичных файлов было бы довольно произвольным, поэтому можно было бы реализовать его как встроенное.

Например, в bash [[ автоматически помещает в кавычки все строки.

[[ abc = $variable ]]

Но в fish это не нужно, потому что не существует поведения разделения пробелов. Кроме того, он автоматически цитирует && , || , < и > потому что это синтаксическая особенность. В fish && - это -a , || - -o . < и > даже не существуют.

В нем также есть оператор =~ . В fish для этого можно использовать тихую команду grep.

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

Кроме того, bash имеет оператор < и > . Они проверяют, какая строка больше или меньше другой строки. Это редко бывает полезно.

И при использовании операторов = и != вы можете использовать синтаксис подстановки, как если бы вы использовали регулярные выражения. Опять же, используйте для этого тихую команду grep.

[[ abc = a* ]]

Кроме того, [[ определяется как -e , -nt , -ot , -ef и ! , но Fish уже имеет их во встроенной test .

Добавление [[ просто добавило бы еще одно ключевое слово, которое не было бы реально обнаружено и не добавило бы особой функциональности. Единственная интересная функциональность - =~ , но тихий grep (или Perl) может делать то же самое, без добавления нового синтаксиса. Кроме того, не стоит добавлять все в оболочку. Я не думаю, что нам нужно иметь встроенное регулярное выражение.

Что ж, я не обязательно имел в виду, что мы должны переопределить bash [[ builtin, скорее, это должно быть представлено как синтаксическая конструкция со своими собственными свойствами. Я имею в виду, что fish разделяет множество ключевых слов и конструкций, которые выглядят как bash, но они разные, поэтому я не понимаю, как это могло быть иначе.

Хотя, исходя из того, что вы сказали, возможно, реализация нашей собственной конструкции test была бы лучшей конструкцией, хотя, переименованная во что-то вроде cond , например, как fish реализует встроенную math вместо из expr . Мы могли бы даже перейти к реализации таких вещей, как <и>, однако, используя естественную (числовую) сортировку вместо лексикографической сортировки, чтобы она работала как с числами, так и со строками.

@Undeterminant builtin [[vs builtin [vs / bin / [небольшие различия уже сбивают с толку в bash; пожалуйста, не надо усугублять ситуацию, добавляя bash - [[vs fish - [[тонкие различия!
Кроме того, дух [[[[] bash нарушает закон ортогональности - он «исправляет» и / или но только для определенных условий, поддерживаемых конструкцией.

Парадоксально, что if commands...; then ...; fi bash легко допускает рыбу и / или между if...then . Но мы не хотим «тогда». Возможно, нужно исправить то, чтобы начать ... конец легче.

Вот странная идея (я совсем не уверен, что она мне нравится):

if (foo; and bar)
  ...
end

В настоящее время (...) в начале команды является недопустимым; естественное чтение - выполнить это и использовать вывод как имя команды, но для этого нам требуется eval .
Если мы уверены, что никогда не позволим такое чтение напрямую, мы могли бы использовать пустые (...) для обозначения begin ...; end .
Отказ от захвата stdout в этой позиции непоследователен, но выглядит очень компактно и чисто.

Что я ненавижу в этом, так это то, что if (...) требует еще одного значения: захватить вывод и присвоить ему некоторую логическую интерпретацию. Например, if (math 2 \< 4) - math не возвращает статус, а выводит 0 или 1 в стандартный вывод. Одно из важных применений - if $saved_bool .
Я не думаю, что это практично - нет единого правильного присвоения логических значений строкам, тем более, что 0/1 безнадежно запутаны. Но когда вы впервые сталкиваетесь с if (...) , это кажется разумным предположением.

Для совместимости укажите общие операторы, которые есть в bash и zsh. Чем проще новым пользователям станет копировать и вставлять большую часть своих прежних функций оболочки, тем выше будет скорость поглощения рыбы. Я обнаружил, что, хотя я люблю рыбу во многих отношениях, некоторые из этих глупых маленьких препятствий просто делают ее больше хлопот, чем преимуществ, когда я перехожу с более чем 15-летними настройками оболочки, которые действительно не должны быть проблемой для поддержки .

Честно говоря, я не рассматриваю && как "маленькое глупое препятствие". Выучить это было бы несложно, если бы вы относились к fish как к собственному языку, а не как к «заменяющей оболочке», как zsh. Если вы прочтете руководство о том, как работает рыба, от начала до конца, я не думаю, что это сложно понять.

Наличие чего-то вроде command1; and command2 делает более ясным, что and - это условное выполнение command2 а не просто какое-то соединение между command1 и command2 .

Но @Undeterminant , вы не видите его так, как большинство людей видят его сначала, когда они впервые обнаруживают его, и т. Д. Пусть это чувство или уровень мастерства придут со временем. Например, я перенес сотни строк из старой устаревшей конфигурации, и, честно говоря, у меня нет времени немедленно преобразовать все, что нужно преобразовать. Я нахожу странности в том, что от fish не возвращается номер строки относительно того, где моя проблема в моих старых конфигурациях.

Я могу понять вашу точку зрения, но она предвзята по отношению к тем, кто хочет внести изменения и хотел бы сделать это с течением времени, а не преодолеть большой горб. Пожалуйста, поймите неправильно, если бы я не заботился о рыбе и, таким образом, попытался бы внести свой вклад, я бы, конечно, просто вернулся к zsh прямо сейчас. Я считаю, что такого рода мысли и рассуждения важны, чтобы немного больше приоткрыть ворота для новичков.

Так что да, вы правы насчет удобочитаемости, но давайте позволим старой работе и выдадим предупреждение, а не ошибку, чтобы отучить людей.

@ylluminate Ты себя обманываешь. Даже если fish поддерживает && вы все равно не можете просто использовать свою конфигурацию из bash или zsh, потому что синтаксис сценариев имеет больше различий, чем просто логические операторы.

Точно. fish функционально отличается, а это означает, что вам не следует просто копировать и вставлять код напрямую. Если ваш код написан на bash, если нет явной необходимости преобразовать его в fish, просто оставьте его как bash; это разные языки.

Так
если я сделаю
команда1 && команда2
в рыбе это означает, что вместо этого я набираю
command1; и command2

Кто-то действительно считает, что (в командной строке) второй вариант чище, футуристичнее и легче набирать?

Он чище, потому что он основан на существующем синтаксисе для выполнения команд, а не на введении нового синтаксиса.

Рассмотрим в 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 builtin или что-то в этом роде?

Я думаю, что это действительно аргумент в пользу того, чтобы сделать фон встроенным, хотя я не предлагаю на самом деле это сделать.

Проблема с ; and и ; or том, что они плохо взаимодействуют с каналами. condition; and echo stuff | grep stuff не работает, а condition && echo stuff | grep stuff работает. Я не вижу другого выхода, кроме как добавить специальный синтаксис.

and echo stuff | grep stuff похоже, у меня работает. Не могли бы вы рассказать, как он сломан?

@ridiculousfish вот случай, который я обнаружил, пробуя рыбу. Выражение or истинно вне оператора if, но (кажется?) Ложным при использовании в операторе if. Если я что-то здесь не упускаю?

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! Поскольку логические значения являются командами, они не имеют особого приоритета.

Вы можете использовать начало / конец как «круглую скобку»:

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

Так что я думаю, что это связано не с трубами, а с приоритетом.

Как вы можете видеть из этой ошибки, существует множество мнений о том, должна ли рыба поддерживать логические операторы :)

Итак, спасибо, ребята, за вложенную здесь энергию.

Я не собираюсь обсуждать, что лучше, а что нет. Это просто практическая вещь.
Как и у большинства из вас, у меня есть свои сценарии, которые нужно запускать. Даже в очень простых вещах условие && гарантирует успешное выполнение команды (выход 0), а ";" просто продолжайте, не заботясь о том, что произошло. Правильно? Значит, они совсем не такие. Надеюсь, мы все с этим согласны. :)

Итак, у меня есть свои скрипты, и ни один из них не работает с рыбой. Да, я часто использую &&. Но это также происходит с любым фрагментом кода в сети с помощью bash, обычно с использованием &&. Короче говоря, дело в том, что я больше не могу использовать свои коды! : D

Мне было интересно ... Можно ли установить функцию или определение в конфигурационном файле рыбы, чтобы исправить ТОЛЬКО это поведение (имеется в виду просто &&) и вернуть его обратно, как в традиционном bash? Является ли это возможным? Правдоподобно? Выполнимо?

Опять же, я согласен с тем, что использование «и» может быть лучше и понятнее. Но это не работает с моим кодом или вообще с любым кодом bash для начинающих. Поэтому вместо изменения уже написанного кода, заменяющего && (... не произойдет ... и, скорее всего, не будет работать), было бы проще позволить Fish понимать традиционный bash, если кто-то хочет или нуждается в нем?

С уважением, ребята, еще раз спасибо за старания !!

Приходились ли мы когда-нибудь ближе к полной совместимости со скриптами bash / zsh ? Я отказался от fish в соответствии с моими предыдущими комментариями, потому что я не собираюсь тратить время на преобразование всей инфраструктуры, которую я уже создал в своей среде оболочки, на таком большом количестве рабочих станций и серверов. С удовольствием попробую еще раз, если мы будем ближе. В противном случае я просто буду продолжать торговать без него. Спасибо.

@rhoconlinux Изменение Fish для поддержки && не заставит ваши сценарии bash работать. Различий намного больше.

Я не понял вашего ответа ^ _ ^
Можно ли определить псевдоним или функцию для проблемы &&?

@rhoconlinux Нет, вам придется модифицировать парсер Fish (в C ++). Я хочу сказать, что если бы Fish действительно поддерживал && , ваши сценарии Bash все равно не запускались бы из-за всех других различий между Fish и 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.
И && , безусловно, проблема №1, с которой я сталкиваюсь.
( export FOO=bar - это # ​​2, но может быть решено с помощью function export; set -x -g (echo $argv | sed 's/=/\n/'); end .)

Однако это не серьезная проблема: я привык печатать
bash , вставка, Ctrl + D.
Хм, хочется добавить сочетание клавиш для запуска текущего / предыдущего
командная строка в bash.

Мои два цента по проблеме:
Я работаю над инструментом развертывания (https://github.com/andres-montanez/Magallanes), который выполняет вызовы команд оболочки, и большинство пользователей и участников будут использовать оболочку bash. Так что, конечно, здесь и там '&&' используются для объединения команд в цепочку.

Есть очевидные обходные пути (например, явная передача всех команд в bash)
Но это приносит ряд болевых точек. Во-первых, могут быть странные побочные эффекты (например, PATH и другие переменные определены по-разному), это означает взлом некоторых основных частей инструмента для этой единственной цели, и мне нужно объединить мои исправления от версии к версии. каждый раз обновляю.

&& - лишь одна из многих функций bash, с которыми Fish несовместима, но она может быть самой простой и широко используемой. Например, указанный выше инструмент находится на PHP, поэтому все сложные задачи выполняются на PHP, и в оболочку передаются только базовые системные команды. Обнаружение несовместимости синтаксиса в таком минимальном варианте использования разочаровывает.

Я полностью согласен с тем, что сказал @cben, что && , на мой взгляд, особый случай, потому что в Интернете есть сотни фрагментов кода, где единственная разница между копированием и вставкой - это поддержка && .
Хотя я согласен с тем, что важно принимать во внимание то, как рыба продвигается вперед с точки зрения синтаксиса и т. Д. Я действительно думаю, что это то, что значительно упростит жизнь многим разработчикам, которые используют или хотят использовать рыбу. Я знаю, что это просто кажется простой заменой && на ; and но это всегда раздражает и заставляет чувствовать себя немного неловко, когда я рассказываю другим людям, насколько прекрасна рыба, но тогда мне приходится возиться и меняют некоторые ключевые слова, они обычно задаются вопросом, зачем мне менять такую ​​простую вещь. Тогда я должен защищать рыбу, и это не лучший вариант для продвижения рыбы.
Иногда самые простые вещи могут иметь наибольшее влияние.
Короче говоря, я полностью поддерживаю синтаксис bash && .

Я согласен с тем, что сказали @Globegitter и @cben . Огромное количество скриптов и программ зависит от && и || . Я использую Fish Shell на своей рабочей станции, и было бы неплохо иметь кросс-шелл-совместимость при написании скриптов.

Учитывая, что между сценариями Fish и Bash есть много существенных различий, помимо && и || , почему все вы, комментируя здесь, полагаете, что заставить Fish принять && будет быть хоть сколько-нибудь значимым? Если вам нужно запустить фрагмент кода Bash, просто запустите bash , выполните фрагмент и затем вернитесь в Fish.

Я думаю, что многие люди хотели бы "обратить" внимание на рыбу, но у них есть инфраструктура, которую можно перенести. У меня, например, есть 15 лет сценариев оболочки только на моей рабочей станции (не говоря уже о других серверах, на которых я бы тоже хотел запускать Fish), которые я не хочу тратить время на преобразование. Я не против ковыряться и заставлять вещи работать «по-рыбному» в течение нескольких месяцев, но я не могу сделать такие первоначальные инвестиции в свой рабочий процесс для перехода на другую оболочку.

Я считаю, что у Fish был бы значительный приток пользователей, если бы была решена общая проблема совместимости, но не похоже, что это является чем-то одним из приоритетов для проекта, исходя из того, что говорят другие, которые работают в разработке Fish. Я слежу за этим именно по этой причине, так как в конечном итоге я бы хотел перейти на рыбалку, если ландшафт изменится в этом отношении.

Что касается простого запуска bash или zsh мере необходимости, в моем случае это было бы значительным объемом запуска этих оболочек, и в противном случае просто глупо идти по этому пути.

@kballard У меня есть идеальный рабочий процесс для 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 Вау, это отличные новости! Большое спасибо.

Похоже, это на самом деле не обрабатывает режим поиска должным образом (не уверен в режиме пейджера; я не понимаю, что именно включает в себя). Нажатие & или | во время поиска прекращает поиск. Тем не менее, я не знаю, как с этим справиться.

Я обновил сценарий, добавив исправление для ввода | или & в многострочную команду.

@kballard Я видел, что пиар приземлился. Значит, скрипт, который вы вставили выше, должен заставить && работать с последним мастером?

Да, должно. Попробуйте и дайте мне знать, если у вас возникнут проблемы.

-Кевин

1 сентября 2014 г. в 01:14 Маркус Падурек [email protected] написал:

@kballard Я видел, что пиар приземлился. Значит, скрипт, который вы вставили выше, должен заставить && работать с последней версией мастера?

-
Ответьте на это письмо напрямую или просмотрите его на GitHub.

Я попробовал этот сценарий с новой версией 2.1.1, выпущенной несколько дней назад, и, похоже, он не работает. Придется ли ждать до 2.2? Спасибо!

@pragmattica : 2.1.1 - это исправление

@xfix : ОК. Спасибо, что дал мне знать. Не могу дождаться 2.2!

УДИВИТЕЛЬНЫЙ: +1:

Есть ли текущий список изменений? Похоже, что корень CHANGELOG сильно устарел.

@pragmattica Теперь, когда echo 'test1' && echo 'test2'; превращается в echo test1 &; and echo 'test2';

Может быть проблема где-то в fish_user_key_bindings.fish ? (Я попытаюсь просмотреть это сам, но мои знания скриптов fish / bash немного шаткие)

Изменить: похоже, что это работает, когда вы вводите команду с помощью && . Было бы неплохо, если бы это случилось в космосе после атаки, но это не очень важно. Здорово, что половина работает :)

-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». Даже если рыба поддерживает операторы && и || , это не гарантирует, что вы можете просто вырезать и вставлять операторы, содержащие эти операторы. Мы не хотим создавать впечатление, что вы можете это сделать. Честно говоря, если вам нужен синтаксис и поведение bash / zsh, вы должны использовать эти оболочки (или альтернативу, заявляющую о совместимости с ними).

Большинство других обсуждаемых идей должны иметь свои собственные проблемы. В частности, может быть некоторая заслуга в реализации некоторых поведений [[ ... ]] , которые впервые были введены ksh88 (не bash). Но, вероятно, путем улучшения встроенной команды test или новой команды, а не путем реализации этих специальных токенов.

Я до сих пор очень обеспокоен тем, что не поддерживает zsh и bash. Я понимаю логику, но не согласен с ней. Некоторое время назад я очень интересовался рыбой, но из-за этого сопротивления отошел. Здесь может быть некоторая возможность форкнуть проект, если нас, как разработчиков, будет достаточно, и они хотели бы, чтобы это было реализовано. Печально видеть это продолжающееся сопротивление, которое в конечном итоге препятствует продвижению вперед и принятию такой интересной работы.

@ylluminate, что вы имеете в виду, "поддерживая zsh и bash?" Какой уровень совместимости вы бы хотели видеть?

Я до сих пор очень обеспокоен тем, что не поддерживает zsh и bash. Я могу понять логику ...

Боюсь, я не понимаю вашей логики в отношении того, что рыба поддерживает функции bash и zsh. Если вам нужна Java, зачем использовать C ++? Если вам нужен Perl, зачем использовать Python? Как только что спросил @ridiculousfish , помимо синтаксического сахара, что еще рыба должна поддерживать, чтобы сделать вас счастливыми? В какой момент рыба просто становится еще одним клоном bash?

PS Я зарабатываю на жизнь программированием с 1979 года и использую UNIX с середины 80-х. Я использовал так много оболочек, что сбился со счета (например, Bourne, Csh, Ksh88, Ksh93, Bash, Zsh, Xonsh). Смена оболочек всегда требует работы (вот почему я не делаю это чаще, чем раз в пять лет или около того). Когда я это делаю, я не жалуюсь, что моя новая оболочка не запускает все мои устаревшие скрипты без изменений.

@ krader1961 Хорошая речь. По моему скромному мнению ...

Я бы не стал все время писать скрипты в fish, как (с последующими заказами):

  1. скрипт рыбы медленный (медленнее чем mksh)
  2. какой-то странный синтаксис (например, ; and , ; or который мне кажется уродливым)
  3. не совместим с posix (я могу сказать, что синтаксис прост, но все же нужно время, чтобы изучить)

Что ж, меня бы не волновали 2 и 3, только если скрипт Fish быстрее, чем другие оболочки (например, mksh, bash).

С другой стороны , я использую рыбу, потому что:

  1. время запуска быстрее, чем у zsh (но медленнее, чем у bash)
  2. по умолчанию включены многие функции (лучше всего - подсветка синтаксиса)
  3. конфигурации хороши и просты (особенно set -Ux )

@ylluminate Глядя на этот выпуск четырехлетней давности, я вижу, насколько ленивые / занятые люди, которые хотят полакомиться рыбой, такой как баш, по-прежнему ленивы / заняты. Страстные создают свою собственную оболочку (например, magicant / yash, elvish / elvish, michaelmacinnis / oh и me :-P). Если вы хотите делать что-то не рыбным, вам, вероятно, понадобится не рыбная раковина.

Если вы действительно думаете о том, как реализовать && || на рыбе и сделать это не очень подозрительным, то вы можете увидеть, что вы просто исключаете begin; end (посмотрите, что делает коммит 594b460ba2d8dca59a3bfd282397c5f33aa9da6f,counter- ; and or играют двойные роли,очень несколько некрасиво) и получить только немного сахара.

@pickfire Не могли бы вы уточнить "сценарий рыбы медленный?" Есть ли какие-нибудь тесты, которые приведут вас к такому выводу?

FWIW в моих тестах fish в целом быстрее, чем 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.

Я думаю, что один из выводов состоит в том, что нам нужен комплексный набор тестов.

@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 впечатляющая скорость.

ls @pickfire fish - это функция в Linux, которая делает некоторые другие вещи для улучшения вывода, чего не делает bash. Если вы хотите сравнить яблоки с яблоками в Linux, используйте command ls . (На Дарвине обертка Fish ls намного тоньше - я должен был указать на это, но я забыл.)

Объяснение "впечатляющей скорости" mksh в вашем тесте состоит в том, что mksh не имеет раскрытия скобок, поэтому он вызывает ls один раз. Очевидно, что однократный вызов ls намного быстрее, чем его вызов 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 была встроенная поддержка параллельного выполнения команд, я думаю, это было бы быстрее всех.

Это время пользователя 0,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 для некоторой команды пути, чтобы мы могли понять, насколько мы далеки от максимальной скорости, которую может предоставить ОС. .

@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: за то, что || и && являются частью синтаксиса рыбы, если это должно быть всенародное голосование.

Рыба - это не баш (или зш). Нет веских причин для реализации && и || кроме как для совместимости с этими оболочками. Совместимость со статус-кво - анти-цель этого проекта.

@Nodd : Ваша ссылка на проблему № 2292 на самом деле является примером того, почему fish не должна реализовывать этот синтаксис. Это было бы еще одним шагом к тому, чтобы заставить людей думать, что fish - это клон POSIX (bash, zsh и т. Д.). Это просто создало бы другие требования, чтобы рыба вела себя как эти раковины в других областях.

Для всех людей, которые ищут решение, начиная с Fish 2.3, я могу подтвердить, что наконец-то есть полностью рабочее решение.

Просто сделайте то, что упоминается выше:

Ну вот. Как только 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

@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 -atter] .fish.

@brj : неправильная проблема для этой функции. Речь идет о «&&» и «||», а не о «!!» - разные вещи.

@faho lol, ты прав. Я всегда получаю уведомление об этой проблеме, поэтому я подумал, что это еще один случай sudo !!.

@Globegitter Извините за путаницу!

Как насчет того, чтобы предложить предлагаемый обходной путь на примере рыбы, чтобы пользователи могли удобно его скопировать? Сообщение об ошибке можно легко дополнить, упомянув об этом. Я продолжаю вставлять один и тот же лайнер (из обзора кода gerrit), где используется &&, потому что он работает практически во всех оболочках (включая Windows cmd.exe, кроме оболочек unix-y). Для меня вышеупомянутый сценарий - средство повышения производительности (я некоторое время набирал bash -c «вставить сюда» ...).

Как мне это сделать && ? Есть разрешение?

Та же проблема, что и выше, я действительно не могу найти способ сделать

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

в рыбе.

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

@ivan пробовал это, но он дает "and" и "./a.out" в качестве аргументов для gcc.

// edit: Между прочим, я закончил использовать скрипт bash, потому что в fish это кажется совершенно невозможным :(

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

Я довольно часто делаю это «совершенно невозможное». Может быть, попробовать синтаксис ; and в чистой рыбной среде? Если не работает, может, у вас что-то не так с точкой с запятой? Вы вводите это в fish, или это передается из другой программы?

@ivan Печатает .

Извините за, наверное, глупый вопрос, но как мне делать скобки? Я не могу найти ни слова о них в документации, и это не совсем тема для Google :(

gcc test2.c -lwlc -o a.out && ((спящий 2 с; ДИСПЛЕЙ =: 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, _ затем_ запускает XServer для этого xterm. xterm ofc аварийно завершает работу до того, как XServer становится готовым.

Ах, прости. Проблема: https://github.com/fish-shell/fish-shell/issues/238

Вы обнаружите, что можете обойти это там, где вы должны, не очень:

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

Когда у вас есть большое количество существующих скриптов для разработки, сборки и внутри скриптов запуска npm, нецелесообразно переключать, тем более, что некоторые / большинство не на fish. Для обычных bash-скриптов с shebang и все такое, конечно же, не проблема.

Самое приятное (или «приятное») в && заключается в том, что он работает с обычными оболочками не только на Linux и Mac, но и даже на Windows, что удобно для быстрой настройки сред разработки и т. Д.

Это ни в коем случае не нарушает условия сделки, но тоже трудно понять, почему его добавление?

Что ж, это довольно глупый аргумент. Почему бы не иметь разные "режимы" для компилятора рыбок? То есть, какую-то настройку, которую вы можете включить, где у вас может быть "чистая" рыба или у вас может быть совместимость с оболочками типа bash вместе с фиш-измами. Вы даже можете иметь разные «уровни» совместимости для других оболочек, чтобы иметь полную совместимость, отсутствие совместимости или что-то среднее между ними. Я имею в виду, что на базовом уровне вы могли бы, по крайней мере, реализовать для этого какой-то компилятор от исходного кода к исходному. Или возьмите код на bash и преобразуйте его во внутреннее промежуточное представление для рыбы. В этом отношении вы могли бы сделать что угодно для перевода. Поправьте меня, если я ошибаюсь, но я считаю, что концепции уровня языка bash et al. по сравнению с рыбой не так уж сильно отличается от мира, верно?

В любом случае, это мои 0,02 доллара по этому вопросу, что действительно кажется глупым, потому что оно построено на предпосылке:

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

когда нет ничего, что мешало бы найти золотую середину между этими двумя понятиями.

Следует, по крайней мере, признать реальность того, что подобные bash раковины намного более стандартны и популярны, чем более эзотерические раковины, такие как рыба, поэтому действительно должен быть какой-то слой совместимости для любой реальной вероятности того, что рыба станет раковиной, способной стоять на ногах. с точки зрения того, что bash широко распространен и не вызывает проблем с совместимостью.

... когда нет ничего, что мешало бы найти золотую середину между этими двумя понятиями.

Ничто иное, как кто-то (или группа людей), вкладывающий более 2000 часов (человеко-год) на написание необходимого кода. Я с нетерпением жду отзыва от вас,

Реализовано в # 4620.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

zx8 picture zx8  ·  3Комментарии

Limeth picture Limeth  ·  3Комментарии

krader1961 picture krader1961  ·  3Комментарии

spacekookie picture spacekookie  ·  3Комментарии

luc-j-bourhis picture luc-j-bourhis  ·  3Комментарии