Як я можу отримати лише поточне ім'я робочої директорії в bash-скрипті, а ще краще, просто термінальній команді.
pwd
дає повний шлях до поточного робочого каталогу, наприклад, /opt/local/bin
але я хочу лишеbin
Як я можу отримати лише поточне ім'я робочої директорії в bash-скрипті, а ще краще, просто термінальній команді.
pwd
дає повний шлях до поточного робочого каталогу, наприклад, /opt/local/bin
але я хочу лишеbin
Відповіді:
Немає необхідності в базовому імені, і особливо немає потреби в підкашлі, що працює під керуванням pwd (що додає додаткову та дорогу операцію вилки ); оболонка може це зробити внутрішньо, використовуючи розширення параметра :
result=${PWD##*/} # to assign to a variable
printf '%s\n' "${PWD##*/}" # to print to stdout
# ...more robust than echo for unusual names
# (consider a directory named -e or -n)
printf '%q\n' "${PWD##*/}" # to print to stdout, quoted for use as shell input
# ...useful to make hidden characters readable.
Зауважте, що якщо ви застосовуєте цю техніку за інших обставин (не PWD
, але якась інша змінна, що містить ім'я каталогу), вам може знадобитися обрізати будь-які проміжні риски. Нижче використовується підтримка extglob bash для роботи навіть з декількома слідовими косою рисою :
dirname=/path/to/somewhere//
shopt -s extglob # enable +(...) glob syntax
result=${dirname%%+(/)} # trim however many trailing slashes exist
result=${result##*/} # remove everything before the last / that still remains
printf '%s\n' "$result"
Як варіант, без extglob
:
dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}" # remove everything before the last /
$PWD
- назва вбудованої змінної bash; всі вбудовані імена змінних містяться у всіх заголовках (щоб їх відрізняти від локальних змінних, які завжди повинні мати хоча б один нижній регістр). result=${PWD#*/}
робить НЕ обчислюватися /full/path/to/directory
; натомість він знімає лише перший елемент, роблячи його path/to/directory
; використання двох #
символів робить відповідність шаблону жадібною, збігаючи якомога більше символів. Детальніше читайте сторінку розширення параметрів, пов’язану у відповіді.
pwd
не завжди є таким самим, як значення $PWD
, через ускладнення, що виникають внаслідок cd
використання символічних посилань, чи має bash -o physical
параметр тощо. Це було особливо неприємно навколо обробки автоматизованих каталогів, де запис фізичного шляху замість логічного створював би шлях, який, якщо він використовується, дозволив би автовиробнику спонтанно демонтувати каталог, який використовується.
sh
і csh
якщо ви хочете клавішу повернення на роботу ви повинні були прочитати всю довідкову stty
сторінку, і нам сподобалося!»
Використовуйте basename
програму. Для вашого випадку:
% basename "$PWD"
bin
basename
програми? Що не так у цій відповіді, окрім пропуску цитат?
basename
дійсно зовнішня програма , яка робить правильно, але працює будь-яку зовнішню програму для речі Баша може робити поза коробки , використовуючи тільки вбудовані функції нерозумно, піддаючись впливом на продуктивність ( fork()
, execve()
, wait()
і т.д.) для без причини.
basename
тут НЕ застосовні до dirname
, так як dirname
має функціональні можливості, які ${PWD##*/}
ні - перетворюючу рядок без косих рис в .
, наприклад. Таким чином, незважаючи на те, що використання dirname
в якості зовнішнього інструменту має накладні витрати, він також має функціонал, який допомагає компенсувати те саме.
function
Ключове слово не сумісне з POSIX, не додаючи ніякого значення над стандартизованим синтаксисом, і відсутність лапок створить помилки в назвах каталогів з пробілами. wdexec() { "./$(basename "$PWD")"; }
може бути кращою альтернативою.
basename
менш "ефективне". Але це, ймовірно , більш ефективним з точкою зору продуктивності розробника , тому що це легко запам'ятати по порівнянні з потворним синтаксисом Баша. Тож якщо ви це пам’ятаєте, ідіть до цього. Інакше basename
працює так само добре. Хто-небудь коли-небудь доводилося вдосконалювати "продуктивність" баш-скрипту і зробити його більш ефективним?
$ echo "${PWD##*/}"
Сігналы абмеркавання
echo "${PWD##*/}"
.
name=${PWD##*/}
було б правильно, і name=$(echo "${PWD##*/}")
було б неправильно (у сенсі непотрібності).
Можна використовувати комбінацію pwd та базової назви. Напр
#!/bin/bash
CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`
echo "$BASENAME"
exit;
Як щодо grep:
pwd | grep -o '[^/]*$'
pwd | xargs basename
не .., мабуть, це не так важливо, але інша відповідь є простішою та послідовнішою у різних середовищах
Мені подобається обрана відповідь (Чарльз Даффі), але будьте обережні, якщо ви знаходитесь у поєднаному режимі і хочете назву цільового реж. На жаль, я не думаю, що це можна зробити в одному виразі розширення параметра, можливо, я помиляюся. Це має працювати:
target_PWD=$(readlink -f .)
echo ${target_PWD##*/}
Щоб побачити це, експеримент:
cd foo
ln -s . bar
echo ${PWD##*/}
повідомляє "бар"
Щоб показати провідні каталоги шляху (не вписуючи fork-exec з / usr / bin / dirname):
echo ${target_PWD%/*}
Це, наприклад, перетворить foo / bar / baz -> foo / bar
readlink -f
це розширення GNU, і тому недоступне для BSD (включаючи OS X).
echo "$PWD" | sed 's!.*/!!'
Якщо ви використовуєте оболонку Bourne або ${PWD##*/}
її немає.
${PWD##*/}
це POSIX sh - кожен сучасний / bin / sh (включаючи тире, золу тощо) підтримує його; щоб потрапити на справжнього Борна на недавній скриньці, вам знадобиться бути в м'яко старувату систему Solaris. Поза тим - echo "$PWD"
; викидання лапок призводить до помилок (якщо в імені каталогу є пробіли, символи підстановки тощо).
Дивно, але ніхто не згадував про цю альтернативу, яка використовує лише вбудовані команди bash:
i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"
Як додатковий бонус, ви можете легко отримати ім’я батьківського каталогу за допомогою:
[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"
Вони працюватимуть на Bash 4.3-альфа чи новіші.
Використання:
basename "$PWD"
АБО
IFS=/
var=($PWD)
echo ${var[-1]}
Поверніть роздільник внутрішніх імен файлів (IFS) назад у простір.
IFS=
Є один пробіл після IFS.
basename $(pwd)
або
echo "$(basename $(pwd))"
pwd
розбивається на рядки та розширюється до того, як передаватись basename
.
basename "$(pwd)"
- хоча це дуже неефективно порівняно з справедливимbasename "$PWD"
, що саме по собі неефективно порівняно з використанням параметра розширення, а не з викликом basename
взагалі.
Для знаходження жокеїв, як я:
find $PWD -maxdepth 0 -printf "%f\n"
$PWD
на, "$PWD"
щоб правильно обробляти незвичні імена каталогів.
Я зазвичай використовую це в скриптах sh
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder
Ви можете використовувати це для автоматизації речей ...
Нижче grep з регулярним виразом також працює,
>pwd | grep -o "\w*-*$"
Просто використовуйте:
pwd | xargs basename
або
basename "`pwd`"
xargs
formultion неефективна і баггі , коли імена каталогів містять символи нового рядка або символи лапок, а друга формулювання викликає pwd
команду в нижній частині, а не отримання того ж результату за допомогою вбудованого змінного розширення.
Якщо ви хочете бачити лише поточний каталог у регіоні запиту bash, ви можете редагувати .bashrc
файл у ~
. Зміна \w
до \W
в рядку:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
Біжи source ~/.bashrc
і він відобразить лише ім'я каталогу в регіоні підказок.
Посилання: /superuser/60555/show-only-current-directory-name-not-full-path-on-bash-prompt
Я настійно вважаю за краще використовувати gbasename
, що є частиною GNU coreutils.
basename
там. Його зазвичай називають gbasename
на MacOS та інших платформах, які в іншому випадку постачаються з базовим іменем, яке не є GNU.
Наступні команди призведуть до друку вашої поточної робочої директорії в скрипті bash.
pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR
$1
міститиме поточну робочу директорію. (2) Тут pushd
і popd
немає ніякої мети, оскільки все, що знаходиться всередині задників, робиться в нижній частині корпусу - так що це не може вплинути на каталог батьківської оболонки для початку. (3) Використання "$(cd "$1"; pwd)"
було б і більш зрозумілим і стійким до імен каталогів з пробілом.