Трохи розгублений, чи є printf в оболонці яшу вбудованою командою чи ні


14

yashОболонка має printfвбудований, в відповідно до його керівництвом .

Однак це я бачу в yashоболонці з конфігурацією за замовчуванням:

kk@eeyore ~ $ command -v printf
/usr/bin/printf
kk@eeyore ~ $ type printf
printf: a regular built-in at /usr/bin/printf

Є printfвбудований в в цій оболонці чи ні? Результат подібний для ряду інших нібито вбудованих утиліт, які також доступні як зовнішні команди.

Для порівняння, в pdksh( kshна OpenBSD, де printfце НЕ вбудований):

$ command -v printf
/usr/bin/printf
$ type printf
printf is /usr/bin/printf

І в bash(де printf є вбудований):

$ command -v printf
printf
$ type printf
printf is a shell builtin

1
Це вбудований - звичайний , а не спеціальний вбудований. Якщо ви плутаєте різницю між спеціальними та звичайними вбудованими версіями або поведінкою, якою відповідає стандарт (див. Пошук команд і виконання 1.eia) - для цього потрібен існування бінарного файлу PATHдля того, щоб регулярно вбудовуватися підлягає виконанню - тоді, будь ласка, поставте своє запитання щодо цього.
мосвій

1
@mosvy Це була деталь стандарту, який мені був невідомий. Якщо ви хочете перетворити це на відповідь, я буду радий. Я не думаю, що мені потрібно було б оновити питання, щоб це було відповідним, оскільки мені не було відомо про цю деталь. Або я напишу це пізніше.
Kusalananda

Відповіді:


14

yashОболонка робить є, і робить використання, вбудований в версію printf(і інших утиліт). Це просто буває дуже педантично сумісним POSIX у тому, як формулює результат команд command -vта type.

Як зауважують mosvy , стандарт POSIX вимагає, щоб звичайна вбудована команда була доступна як зовнішня команда $PATHдля вбудованої версії команди, яка виконується.

Це відповідний текст із стандарту :

Пошук і виконання команд

Якщо проста команда призводить до імені команди та необов'язкового списку аргументів, слід виконати такі дії:

  1. Якщо ім'я команди не містить жодних символів <slash>, повинен відбутися перший успішний крок у наступній послідовності:

    • а. Якщо ім'я команди відповідає імені спеціальної вбудованої утиліти, ця спеціальна вбудована утиліта буде викликана.

      [...]

    • е. В іншому випадку команду слід шукати за допомогою змінної середовища PATH, як описано в змінних середовища XBD:
      • i. Якщо пошук вдалий:
        • а. Якщо система реалізувала утиліту як звичайну вбудовану або як функцію оболонки, вона буде викликана в цей момент у пошуку шляху.
        • б. В іншому випадку оболонка виконує утиліту в окремому середовищі утиліти [...]
          [...]
      • ii. Якщо пошук не вдався, команда завершиться невдачею зі статусом виходу 127, а оболонка напише повідомлення про помилку.
  2. Якщо ім'я команди містить щонайменше один <косий рядок>, [...]

Це означає, що вихід command -v printfозначає, що printfкоманда була знайдена в шляху пошуку, тоді як вихід type printfдодає до цього, що команда є звичайною вбудованою.

Оскільки printfкоманда була знайдена в шляху пошуку, а оскільки вона є звичайною вбудованою оболонкою, yashвикличе її вбудовану версію команди . Якщо в шляху неprintf було знайдено і якщо оболонка працювала в правильному режимі POSIX, натомість буде створена помилка.yash

yashпишається тим, що оболонка, сумісна з POSIX, і це також справедливо, якщо ми подивимось, що POSIX говорить проcommand -v :

-v

Наведіть рядок до стандартного виводу, який вказує ім'я шляху або команду, яка буде використовуватися оболонкою в поточному середовищі виконання оболонки (див. Середовище виконання оболонки ), щоб викликати command_name, але не викликати command_name.

  • Утиліти, звичайні вбудовані утиліти , command_namesвключаючи <slash>символи, та будь-які функції, визначені реалізацією, які знаходять за допомогою PATHзмінної (як описано в пошуку та виконанні команд ), повинні записуватися як абсолютні імена шляхів .

3
Хтось знає, чому POSIX вимагає існувати зовнішню команду перед запуском вбудованої команди?
студог

@studog Ви можете задати це як окреме нове запитання, можливо, посилаючись на цю відповідь та / або питання.
Kusalananda


6

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

printfє одним з таких "регулярних" вбудованих. У рідному режимі його завжди викликають, незалежно від того, чи існує зовнішня команда, знайдена цим іменем.

$ PATH = / usr / bin 
$ printf
printf: для цієї команди потрібен операнд
$ type printf
printf: звичайний вбудований в / usr / bin / printf
$
$ PATH = / 
$ printf
printf: для цієї команди потрібен операнд
$ type printf
printf: звичайний вбудований (не знайдено в $ PATH)
$

Але коли встановлено posixly-correctпараметр оболонки, це лише вбудована, якщо зовнішня команда може бути знайдена на PATH.

$ set - правильний вираз
$
$ PATH = / usr / bin 
$ printf
printf: для цієї команди потрібен операнд
$
$ PATH = / 
$ printf
yash: немає такої команди `printf '
$

Це насправді відповідає тому, що говорить Єдина специфікація Unix, і говориться щонайменше з 1997 року.

Він відрізняється від оболонки Z, оболонки 93 Korn, оболонки Bourne Again і оболонки Debian Almquist, жодна з яких не реалізує та не документує таку поведінку для звичайних вбудованих модулів. Наприклад, оболонка Z, наприклад, документи, які регулярно вбудовуються, завжди знайдеться перед кроком, який шукає PATH. Так само і оболонка Almquist Debian. І саме це роблять ці оболонки, навіть якщо вони викликаються як shу своїх параметрах включення-POSIX.

% / bin / exec -a sh zsh -c "PATH = /; введіть printf; printf"
printf - вбудована оболонка
zsh: printf: 1: недостатньо аргументів
% / bin / exec -a sh ksh93 -c "PATH = /; введіть printf; printf"
printf - вбудована оболонка
Використання: printf [параметри] формату [рядок ...]
% / bin / exec -a sh bash --posix -c "PATH = / type printf; printf"
printf - вбудована оболонка
printf: використання: printf [-v var] формат [аргументи]
% / bin / exec -a sh dash -c "PATH = /; введіть printf; printf"
printf - вбудована оболонка
sh: 1: printf: використання: printf формат [арг ...]
% 

Однак не запускається, printfколи він не PATHзнаходиться на поведінці оболонки PD Korn, оболонки Heirloom Bourne та оболонки MirBSD Korn; тому що вони не мають printfвбудованого в першу чергу. ☺

% / bin / exec -a sh `команда -v ksh` -c" PATH = /; введіть printf; printf "
printf не знайдено
sh: printf: не знайдено
% / bin / exec -a sh `команда -v oksh` -c" PATH = /; введіть printf; printf "
printf не знайдено
sh: printf: не знайдено
% / bin / exec -a sh `команда -v jsh` -c" PATH = /; введіть printf; printf "
printf не знайдено
sh: printf: не знайдено
% / bin / exec -a sh mksh -c "PATH = /; введіть printf; printf"
printf не знайдено
sh: printf: не знайдено
% ksh -c "тип printf; printf"
printf - це відстежений псевдонім для / usr / bin / printf
використання: формат printf [аргументи ...]
% oksh -c "тип printf; printf"
printf - це відстежений псевдонім для / usr / bin / printf
використання: формат printf [аргументи ...]
% jsh -c "тип printf; printf"
printf хешировано (/ usr / bin / printf)
використання: формат printf [аргументи ...]
% mksh -c "тип printf; printf"
printf - це відстежений псевдонім для / usr / bin / printf
використання: формат printf [аргументи ...]
$

Добре! Дякуємо за підтвердження та за те, що ви додали до моїх значень специфічні для оболонки шматочки! Мені вже подобається ця оболонка.
Kusalananda

-1

Формулювання може бути вдосконалено.

Якщо оболонка знаходиться в режимі posix set --posixly-correct:

Для звичайних вбудованих модулів, які не існують у PATH, друкується:

pushd: a regular built-in (not found in $PATH)

Це чіткий опис: це вбудований, але в PATH не існує виконавчого файлу з таким же ім'ям.

Однак для звичайних вбудованих назв, які також існують у PATH, це друкується:

echo: a regular built-in at /bin/echo

Що, мабуть, означає, що виконуваний файл в / bin / echo буде виконаний (чого не буде). Я пропоную змінити atна also found in PATH at:

echo: a regular built-in also found in PATH at /bin/echo

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


У режимі POSIX жоден звичайний вбудований не працюватиме, якщо він також не знайдеться в PATH.

Однак обидва (POSIX) спеціальні:

break colon continue dot eval exec exit export
readonly return set shift times trap unset

І напівспеціальний яш (не спеціальний для POSIX):

alias bg cd command false fc fg getopts jobs
kill pwd read true umask unalias wait

вбудовані досі працюють.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.