Изменить каталог в функции fish и вернуться в исходный каталог после прерывания

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

В bash это было просто:

function omake {(
  cd $SOURCE_ROOT;
  make $@;
)}

Поскольку у рыбы нет подоболочек, лучшее, что я смог сделать, это:

function omake
    pushd
    cd $SOURCE_ROOT
    make $argv
    popd
end

Это работает, но с оговоркой, что после прерывания версии fish с помощью ^C оболочка все еще находится в $SOURCE_ROOT, но прерывание версии bash возвращает меня в исходный каталог.

Есть ли способ написать скрипт, который работает так же, как bash в fish?


person Tiki    schedule 20.03.2014    source источник


Ответы (3)


Это настолько близко, насколько я могу добраться до подоболочки:

function omake
    echo "cd $SOURCE_ROOT; and make \$argv" | fish /dev/stdin $argv
end

Замена процесса, похоже, не может быть прервана: Ctrl-C не останавливает эту спящую команду

echo (cd /tmp; and sleep 15)

Однако у fish есть очень хороший способ найти pid фонового процесса:

function omake
    pushd dir1
    make $argv &
    popd
end

Затем, чтобы остановить создание, вместо Ctrl-C выполните kill %make

person glenn jackman    schedule 20.03.2014

если вы используете GNU coreutils, вы можете использовать env для этого (как предложил пользователь 2394284).

env -C foo pwd

это запустит pwd в подкаталоге с именем foo. это обычно хорошо взаимодействует с рыбой, например, это может быть красивый фон

документы говорят:

Измените рабочий каталог на dir перед вызовом команды. Это отличается от встроенного в оболочку cd тем, что он запускает команду как подпроцесс, а не изменяет собственный рабочий каталог оболочки; это позволяет связать его с другими командами, которые запускают команды в другом контексте.

person Sam Mason    schedule 06.12.2018

В частности, для make вы можете использовать его параметр -C:

function omake
    make -C $SOURCE_ROOT $argv
end

Многие другие программы используют опцию -C. На макушке: ниндзя, мерзавец

В противном случае, если вы все равно довольны подоболочкой, автономный скрипт дает вам именно это, с тем преимуществом, что вы можете написать его на любом языке, от Python до C, и вам не придется переписывать его, когда вы хотите изменить твоя оболочка.

Это можно написать на любом языке:

#!/usr/bin/env fish
cd $SOURCE_ROOT
and exec make $argv

Однако, что меня действительно беспокоит, так это вопиющее упущение опции -C в env! Env может устанавливать переменные среды и запускать программы; ясно, что было бы хорошо иметь возможность также установить рабочий каталог! Вот рудиментарный cdrun скрипт, чтобы компенсировать это:

#!/usr/bin/env fish
cd $argv[1]
and exec env $argv[2..-1]

or

#!/bin/sh
set cd="$1"
shift
cd "$cd" &&
exec env "$@"

Вооружившись командой cdrun, ваша функция omake будет такой же простой, как:

function omake
    cdrun $SOURCE_ROOT make $argv
end

or

omake() {
    cdrun "$SOURCE_ROOT" make "$@"
}
person user2394284    schedule 15.04.2016