Чому lsдля його виконання потрібен окремий процес? Я знаю причину, чому такі команди, як cdне можна виконувати за допомогою механізму forking, але чи є шкода, якщо lsвони виконуються без розгортання?
Чому lsдля його виконання потрібен окремий процес? Я знаю причину, чому такі команди, як cdне можна виконувати за допомогою механізму forking, але чи є шкода, якщо lsвони виконуються без розгортання?
Відповіді:
Більш-менш відповідь ls- це зовнішній виконуваний файл. Ви можете побачити його місцезнаходження, запустивши type -p ls.
Чому тоді не lsвбудований в оболонку? Ну чому це має бути? Завдання оболонки - не охоплювати всі наявні команди, а забезпечувати середовище, здатне виконувати їх. Деякі сучасні оболонки мають echo, printfі їх називають вбудованими, які технічно не повинні бути вбудованими, але зроблені так з міркувань продуктивності, коли вони запускаються повторно (насамперед у щільних петлях). Не роблячи їх вбудованими, оболонка повинна буде розщедритися та виконати новий процес для кожного дзвінка до них, який може бути дуже повільним.
Як мінімум, запущений lsзовнішній виконуваний файл вимагає запуску однієї з сімейств exec системних викликів. Ви можете це зробити, не розвантажуючи, але це замінить первинну оболонку, яку ви використовуєте. Ви можете побачити, що відбувається в цьому випадку, виконавши наступне:
exec ls; echo "this never gets printed"
Оскільки зображення процесу вашої оболонки замінено, поточна оболонка більше не доступна після цього. Щоб оболонка могла продовжувати працювати після запуску ls, команда повинна бути вбудована в оболонку.
Форкінг дозволяє замінити процес, який не є вашою основною оболонкою, а це означає, що ви можете продовжувати запускати оболонку згодом.
echo, printfі так далі
cdне зовнішній виконуваний файл?
cdвиконуваний в POSIX-сумісних операційних систем ( дивіться тут ). Якщо ви хочете насправді chdir () в поточному процесі, вам потрібно, щоб він був вбудований в оболонку.
У Довідковому посібнику Баша зазначено:
Команди вбудованих необхідні для реалізації функціональних можливостей, неможливих або незручних для отримання за допомогою окремих утиліт.
Тобто, снаряди призначені для тільки включає вбудовані команди , якщо:
lsКоманда не відповідає ні одному з перерахованих вище вимоги.
Однак , тут немає жодного обмеження в програмуванні, яке не дозволило б lsзадіяти вбудований, який виконується в тому ж процесі, що і інтерпретатор bash. Причини дизайну для команд, які не включаються як вбудовані оболонки:
Щодо першої причини - Ви хочете, щоб оболонка була максимально незалежною та стійкою. Ви не хочете, щоб оболонка застрягла на lsкріпленні NFS, який "не реагує на спроби"
Щодо другої причини - у багатьох випадках ви можете використовувати оболонку для системи, яка використовує Busybox або іншу файлову систему, яка має іншу lsреалізацію. Або навіть використовувати одне і те ж джерело оболонки в ОС, які мають різні lsреалізації.
Щодо третьої причини - для таких виразів, як find . -type d | xargs ls -ladце було б важко або неможливо здійснити lsв тому ж процесі, що і інтерпретатор оболонки.
Щодо четвертої причини - Деякі lsкоманди можуть зайняти тривалий час. Можливо, ви хочете, щоб оболонка тим часом продовжувала робити щось інше.
Примітка: Дивіться цей пост за Уоррен Янг у відповідь на подібне питання.
lsу зовнішній процес. Це можна було б зробити, але це було б складно.
bashвихід alias | grep ls. вхідcat /etc/passwd | while read a; do echo "$a"; done
lsне потребує окремого процесу. Дуже мало команд насправді вимагає окремого процесу: лише ті, яким потрібно змінити привілеї.
Як правило, оболонки реалізують команди як вбудовані лише тоді, коли ці команди потрібно реалізувати як вбудовані. Такі команди, якalias , cd, exit, export, jobs, ... потрібно прочитати або змінити деякий внутрішній стан оболонки, і , отже , не можуть бути окремі програми. Команди, які не мають таких вимог, можуть бути окремими командами; таким чином, їх можна викликати з будь-якої оболонки або іншої програми.
Дивлячись на список вбудованих файлів у bash, лише наступні вбудовані файли можуть бути реалізовані як окремі команди. Для деяких з них може бути невелика втрата функціональності.
command- але він втратить свою корисність у ситуаціях, коли PATHможе бути не налаштовано належним чином, а сценарій використовується commandяк частина його налаштування.echo - це вбудований для ефективності.help - він може використовувати окрему базу даних, але вбудовування довідкового тексту у виконувану оболонку має перевагу зробити оболонку виконуваною самостійно.kill - є дві переваги в наявності вбудованого модуля: він може розпізнавати позначення робочих місць на додаток до ідентифікаторів процесів, і його можна використовувати навіть тоді, коли не вистачає ресурсів для запуску окремого процесу.printf- з тієї ж причини echo, що і для підтримки-v опції розміщення виводу в змінну.pwd - вбудований пропонує додаткову можливість логічного відстеження поточного каталогу (залишаючи символьні посилання недоторканими, а не розширюючи їх).test- це вбудований для ефективності (і bash також робить деякі магії з файлами, викликаними /dev/fd/…в деяких операційних системах).Кілька оболонок пропонують значну кількість додаткових вбудованих конструкцій. Там в стулці , яка є оболонкою призначена для автономного довічних для аварійного ремонту (коли деякі зовнішні команди можуть не працювати). У ньому є вбудований ls, званий -ls, а також інші інструменти, такі як -grepі -tar. Вбудовані Sash мають менше можливостей, ніж повноцінні команди. Zsh пропонує деякі подібні вбудовані модулі zsh / files . Він не має ls, але розширення підстановки ( echo *) zstatможе виконувати подібну функцію.
Я думаю, що тут чогось не вистачає людям - це складна складність програми GNU lsв Linux. Порівнюючи виконуваний розмір lsдо bashі dashоболонок на моїй Debian, ми бачимо , що це досить великий:
graeme@graeme:~$ ls -lh /bin/{ls,bash,dash}
-rwxr-xr-x 1 root root 953K Mar 30 2013 /bin/bash
-rwxr-xr-x 1 root root 115K Dec 25 20:25 /bin/dash
-rwxr-xr-x 1 root root 108K Jul 20 22:52 /bin/ls
Включення такої lsповноцінної, як версія GNU до bashзбільшить виконуваний розмір на 10%. Він майже такого ж розміру, як і повнийdash оболонка!
Більшість вбудованих оболонок вибрані тому, що вони інтегруються з оболонкою таким чином, що зовнішні виконувані файли не можуть (питання вказує cd, але іншим прикладом є bash версія killінтеграції з контролем роботи bash) або тому, що вони дуже прості команди для реалізації, що дає велику швидкість порівняно з розміром ( trueі falseнастільки ж просто, як це стає).
У GNU lsбув тривалий цикл розробки, і реалізація може запропонувати варіанти налаштування того, як / як відображаються результати. Використання вбудованого ls за замовчуванням може або втратити цю функціональність, або значно збільшить складність і розмір оболонки.
Виконайте те, що шукаєте:
printf "%s\n" *
Також ви можете зберігати назви файлів у масиві:
files=(`printf "%s\n" *`) #items are separated by whitespace
echo ${#files[*]} files
for index in ${!a[*]}
do printf "%d: %s\n" $index ${a[$index]};
done
Але це не стосується пробілів в іменах.
Це переходить до змінної і не хвилює пробілів:
printf "%s\n" * | while read a; do echo $a; done
lsце зовнішня програма,echo *абоecho * .*(залежно від параметрів оболонки) виконує досить непогану роботу з перерахуванням файлів без розгортання.