Возможно ли выполнить подмену команд оболочки без использования подшивки?

Создайте запись ~ / .ssh / config для виртуальных машин, которые вы постоянно воссоздаете. Пример ниже. Это означает, что вам не нужно постоянно взламывать файл ~ / .ssh / known_hosts .

Host test-vm-1
    StrictHostKeyChecking no
11
04.08.2016, 03:22
3 ответа

Выбор заголовка вашего вопроса немного сбивает с толку.

pushd / popd , функция csh , скопированная с помощью bash и zsh , представляют собой способ управления стеком. запоминаемых каталогов.

pushd /some/dir

помещает текущий рабочий каталог в стек, а затем изменяет текущий рабочий каталог (и затем печатает / some / dir , за которым следует содержимое этот стек (разделенный пробелами).

popd

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

(также имейте в виду, что некоторые каталоги будут будут представлены там с их нотацией ~ / x или ~ user / x ).

Итак, если стек в настоящее время имеет / a и / b , текущий каталог - / здесь , и вы работаете:

 pushd /tmp/whatever
 popd

pushd напечатает / tmp / something / here / a / b и popd выведет / здесь / a / b , а не / tmp / something Независимо от того, используется ли подстановка команд или нет. popd не может быть использован для получения пути к предыдущему каталогу, и, как правило, его вывод не может быть обработан постобработкой (см. Массив $ dirstack или $ DIRSTACK некоторые оболочки, хотя для доступа к элементам этого стека каталогов)

Может быть, вы хотите:

pushd "$(mktemp -d)" &&
popd &&
rmdir "$OLDPWD"

Или

cd "$(mktemp -d)" &&
cd - &&
rmdir "$OLDPWD"

Хотя я бы использовал:

tmpdir=$(mktemp -d) || exit
(
  cd "$tmpdir" || exit # in a subshell 
  # do what you have to do in that tmpdir
)
rmdir "$tmpdir"

В любом случае, pushd "$ (mktemp -d ) " не запускает pushd в подоболочке. В противном случае он не смог бы изменить рабочий каталог. Это mktemp , работающий в подоболочке. Поскольку это отдельная команда, она должна выполняться в отдельном процессе. Он записывает свой вывод в канал, а процесс оболочки читает его на другом конце канала.

ksh93 может избежать отдельного процесса, когда команда встроена, но даже там это все еще подоболочка (другая рабочая среда), которая на этот раз эмулируется, а не полагается на отдельную среду, обычно обеспечиваемую разветвлением. Например, в ksh93 , a = 0; echo "$ (a = 1; эхо-тест)"; echo "$ a" , форк не задействован, но все же echo "$ a" выводит 0 .

Здесь, если вы хотите сохранить вывод mktemp в переменной, одновременно с передачей его в pushd с помощью zsh , вы можете:

pushd ${tmpdir::="$(mktemp -d)"}

С другими оболочками типа Борна:

unset tmpdir
pushd "${tmpdir=$(mktemp -d)}"

Или использовать вывод $ (mktemp -d) несколько раз без явного сохранения его в переменной, вы можете использовать zsh анонимные функции:

(){pushd ${1?} && cd - && rmdir $1} "$(mktemp -d)"
10
27.01.2020, 19:58

В bash, каталоги предоставляют список запомненных каталогов методом pushd / popd.

Кроме того, dirs -1 печатает последний каталог, включенный в список.

Итак, чтобы удалить каталог, созданный ранее путем выполнения pushd $ (mktmp -d) , используйте:

rmdir $(dirs -1)

А затем popd уже удаленный каталог из списка:

popd > /dev/null

Все в одной строке:

rmdir $(dirs -1); popd > /dev/null

И добавление опции (-l), чтобы избежать записи ~ / x или ~ user / x :

rmdir $(dirs -l -1); popd > /dev/null

Что замечательно похоже на строку, которую вы просили.
За исключением того, что я бы не стал использовать &> , так как это скроет сообщения об ошибках popd .

Примечание. Каталог останется после rmdir , поскольку в этот момент он является pwd . И будет фактически отключен после команды popd (оставшиеся ссылки не используются).


Есть возможность использовать для оболочек, которые поддерживают переменную "OLDPWD" (большинство оболочек типа bourne: ksh, bash, zsh имеют $ OLDPWD ). Интересно отметить, что ksh не реализует dirs, pod, pushd по умолчанию (lksh, dash и другие также не имеют popd, поэтому здесь их нельзя использовать):

popd && rmdir "$OLDPWD"

Или, более идиоматический (тот же список оболочек, что и выше):

popd && rmdir ~-
0
27.01.2020, 19:58

Вы можете сначала отключить каталог, прежде чем покинуть его:

rmdir "$(pwd -P)" && popd

или

rmdir "$(pwd -P)" && cd ..   # yes, .. is still usable

, но обратите внимание, что pushd и popd действительно инструменты для интерактивных оболочек. , а не для скриптов (вот почему они такие болтливые; настоящие скриптовые команды молчат, когда они успешны).

2
27.01.2020, 19:58

Теги

Похожие вопросы