Оболочка fish и выполнение программ из bash через `function`

В настоящее время я пытаюсь запустить редактор атомов в оболочке bash, из оболочка fish. Важно, чтобы я запускал atom в bash из-за того, как ide-haskell обрабатывает разрешение пути ghc-mod, а также из-за некоторых других проблем со стандартизацией.

Вот как я к этому шел:

#~/.config/fish/config.fish

function start-atom
  bash $HOME/lib/atom/bin/Atom/atom $argv
end

Однако, когда я пытаюсь запустить start-atom из fish, я получаю следующую ошибку:

/home/athan/lib/atom/bin/Atom/atom: /home/athan/lib/atom/bin/Atom/atom: cannot execute binary file

Хотя я знаю, что этот файл правильный и исполняемый. Любые идеи? Благодарю вас!


person Athan Clark    schedule 08.01.2015    source источник
comment
В чем прикол atom? Если он начинается с #!/bin/bash, он будет запущен с bash, несмотря ни на что.   -  person Charles Duffy    schedule 08.01.2015
comment
... если вместо этого вы полагаетесь на функциональность, добавленную с помощью ваших ~/.bashrc, ~/.bash_profile и т. д., то вы все равно не получите этого с тем, что вы делаете, поскольку они предназначены только для interactive оболочки.   -  person Charles Duffy    schedule 08.01.2015
comment
(по совершенно другой теме - функции оболочки и псевдонимы имеют очень разную семантику; функция не является подтипом псевдонима).   -  person Charles Duffy    schedule 08.01.2015
comment
@Charles, в рыбе псевдоним реализован как функция. alias foo bar превращается в function foo; bar $argv; end   -  person glenn jackman    schedule 08.01.2015
comment
@glennjackman, это делает псевдоним типом функции, а не делает функцию типом псевдонима.   -  person Charles Duffy    schedule 08.01.2015


Ответы (2)


Когда вы запускаете bash file_name, это означает, что вы пытаетесь запустить file_name как сценарий bash.

Попробуйте это вместо этого:

bash -c '$HOME/lib/atom/bin/Atom/atom "$@"' dummy $argv

-c означает «запустить эту команду с помощью bash» вместо «запустить этот скрипт с помощью bash».

Как указал Чарльз в комментариях, нам нужно немного настроить, чтобы передать параметры команде. Мы передаем их в bash, который будет использовать их в качестве позиционных параметров внутри предоставленной команды, следовательно, $@.

person Mr. Llama    schedule 08.01.2015
comment
Это означает, что заданный argv будет передан оболочке, а не сценарию atom (поэтому аргументы будут в $@ при запуске $HOME/lib/atom/bin/Atom/atom). Это действительно то, что мы хотим здесь? Я думаю, мы бы хотели, чтобы argv передавался самому сценарию atom. - person Charles Duffy; 08.01.2015
comment
... который, если atom имеет надлежащие права на исполняемый файл и шебанг, например, для автоматического вызова bash, будет просто $HOME/lib/atom/bin/Atom/atom $argv в рыбе. - person Charles Duffy; 08.01.2015
comment
... в противном случае это может быть что-то более похожее на bash -c "$HOME"'/lib/atom/bin/Atom/atom "$@"' $argv, но потенциально с некоторыми исправлениями для рыбы. (Дело в том, что если команда, переданная с -c, не ссылается на $@, дополнительные аргументы будут проигнорированы). - person Charles Duffy; 08.01.2015
comment
@CharlesDuffy - Ах, похоже, я неправильно понял справочные страницы. В нем указано -c string If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.. Я предположил, что это имело в виду позиционные параметры команды, а не сам bash. - person Mr. Llama; 08.01.2015

должно быть: bash -c '$HOME/lib/atom/bin/Atom/atom "$@"' _ $argv

Подчеркивание станет $0 bash

Демо:

$ function test_bash_args
      bash -c 'printf "%s\n" "$@"' _ $argv
  end
$ test_bash_args one two three
one
two
three

Если вам нужен этот сеанс bash для загрузки ваших конфигураций, сделайте его оболочкой входа в систему.

Итак, итог: ~/.config/fish/functions/start-atom.fish

function start-atom
    bash -l -c '$HOME/lib/atom/bin/Atom/atom "$@"' _ $argv
end
person glenn jackman    schedule 08.01.2015