Як явно викликати вбудовану оболонку?


14

Я хочу налаштувати функціональність cdкоманди відповідно до моїх потреб.

Я визначив наступну функцію - function cd () { cd "$@" && pushd "$@"; }

Метою цієї функції є автоматичне натискання каталогу на стек, щоб це заощаджувало мені зусилля pushd .щоразу вводити вручну .

Однак наведена вище функція є нескінченно рекурсивною функцією, оскільки виклик до cdінтерпретується як сама функція, а не cdвбудована.

Як я посилаюсь на cdвбудований у цій функції?

Я знаю, що псевдоніми можна уникнути, використовуючи \. Який спосіб вийти з функцій або посилатися на вбудовані більш чіткі способи?

Примітка. Я не хочу перейменовувати свою функцію ні на що інше.


3
Чому б не просто alias cd=pushd? Що ви очікуєте, що станеться, коли ви перейдете на щось, що не є абсолютним шляхом (наприклад, cd ../)?
Патрік

@Patrick pushdне підтримує -P. Але ви праві, як показано в питанні, function cdвиглядає трохи неправильно, оскільки він змінив каталог двічі.
Тіно

Відповіді:


6

У commandBUILTIN сила ім'я команди повинна інтерпретуватися як вбудована , так і зовнішня команда (пропуск псевдоніма і функція пошуку). Він доступний у всіх оболонках POSIX, включаючи bash.

cd () { command cd "$@" && pushd "$@"; }

(Зверніть увагу, що цей приклад поганий: він не працює з відносними шляхами, і ви також можете просто ввести pushdв першу чергу.)

У bash та zsh (але не ksh) ви можете використовувати builtinдля примушування ім'я команди інтерпретувати як вбудований, виключаючи псевдоніми, функції та зовнішні команди.


16

У Bash є (вбудована) команда builtin, яка робить саме те, що вам потрібно. Заміна cdз builtin cdв функції зафіксує рекурсию.


1

Я підозрюю, що ти кажеш, що "не хочеш перейменувати свою функцію ні на що інше", ти маєш на увазі, що ти хочеш мати можливість викликати свою функцію за тим же ім'ям, що і вихідна команда.

Отже, ще один спосіб зробити це, що також працює для речей, які не є вбудованими, - це назвати свою функцію чимось іншим, а потім визначити псевдонім для загорнутої команди. Це працює, тому що псевдонім не існує в контексті виконання вашої функції.

Приклад wrapper.sh:

#!/bin/bash
function my_wrapper() { wrapped_program $@ && dostuff }

І, наприклад, у .bash_aliases:

source /path/to/wrapper.sh
alias wrapped_program="my_wrapper"

Але це досить хакі. Використання commandбажано, коли це можливо.


-1

Для цього для відносних шляхів знадобиться наступне:

function cd { 
   dir="$(realpath "$@")"
   command cd "$dir"
   pushd "$dir"
}

Це передбачає, що ви перебуваєте у досить сучасному дистрибутиві Linux, який містить утиліту 'realpath'. (Наприклад, RHEL 6). Якщо Perl доступний, "realpath" можна змоделювати за допомогою:

! realpath $(pwd) > /dev/null 2>&1  && function realpath {
    perl -e "use Cwd realpath; print realpath(\"$1\") . \"\\n\";"
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.