Різниця продуктивності між аргументом stdin та аргументом командного рядка


11

Для деяких команд можна вказати певний вхід як аргумент stdin або аргумент командного рядка.

Зокрема, припустимо, що commandаргумент командного рядка може приймати введення stdin та ім'я файлу, і command < myfile, cat myfile | command і command myfileможе дати такий же результат.

Наприклад,

Коли команда sed:

sed s/day/night/ <myfile >new   
sed s/day/night/ myfile >new    
cat myfile | sed s/day/night/ >new

Коли команда cat:

cat < myfile
cat myfile
  1. Мені було цікаво, чи є якісь загальні правила щодо їх виступу, тобто яке з них, як правило, є найбільш ефективним, а яке найменше?
  2. Чи перенаправлення завжди краще, ніж труба?

1
Я хочу, щоб усі, хто задає ці (дублюються) запитання, писали і писали власну оболонку з нуля, як вправу.
alex

1
будь ласка, не використовуйте "Спасибі!" у ваших питаннях. Проголосуйте відповіді вгору, щоб висловити свою вдячність.
alex

@Alex: Якщо це дуп, будь ласка, посилання на дублікат, і ми будемо працювати над його закриттям. Як правило, ви б утрималися відповідати на запитання, яке ви знаєте, як дублікат, і позначте його для уваги модератора.
Калеб

1
@alex: Де я можу навчитися писати власну оболонку?
Тім

@Caleb: Я впевнений, що про це запитували як 2 або 3 рази за останній місяць, просто не майте посилання під рукою :-p
alex

Відповіді:


6

cat file | commandСинтаксис вважається Непотрібне використанняCat . З усіх ваших варіантів потрібен показник продуктивності, оскільки він повинен породити ще один процес у ядрі. Як би незначним це не виявилося у великій картині, це накладні витрати інших форм. Це було висвітлено з питань, таких як: Чи слід мені піклуватися про зайвих котів?

Між іншими двома формами практично немає відмінностей у роботі. STDIN - це спеціальний файловий вузол, який процес має відкривати та читати так само, як і будь-який інший. Передача імені файлу замість STDIN просто змушує його відкрити інший файл.

Різниця полягала б у тому, які функції / гнучкість ви шукаєте.

  • Передача імені файлу програмі означало б, що вхідний файл можна шукати. Це може не мати значення для програми, але деякі операції можуть бути виконані, якщо потік шукається.
  • Знання фактичного вхідного файлу дозволяє вашій програмі потенційно писати на нього. Наприклад, sed -iдля редагування на місці. (Примітка. Оскільки для цього потрібно створити новий файл за кадром, це не збільшення продуктивності порівняно з іншими переадресаціями, але це зручність.)
  • Використання переадресації оболонки дає можливість об'єднати декілька файлів або навіть використовувати перенаправлення процесу. sed [exp] < file1 file2або навіть sed [exp] < <(grep command). Детальну інформацію про цей випадок використання можна знайти в цьому запитанні: Заміна процесу та подача труб

Заміна процесу повинна працювати, не вимагаючи від вас результату; sed [exp] < <(grep command)працюватиме так само добре sed [exp] <(grep command)(оскільки <(grep command)створює іменований тимчасовий файл довжиною команди, яка sedцілком здатна відкриватися самостійно без допомоги оболонки).
ShadowRanger

2
  1. З огляду на те, що command fileпросто відкриває файл і з цього моменту працює, як якщо б він був stdin, різниці мало. За допомогою перенаправлення оболонки ви просто заздалегідь відкриваєте файл (оболонка робить,) на відміну від самої команди.

  2. Якщо ми говоримо про cat file | commandvs. command <file, то останнім вважається кращим. Ви не збираєтесь помічати значну різницю в роботі між цими двома, але перша є зайво складною (додатковий процес і буфер спільної пам’яті для труби з обмеженою пропускною здатністю). Ви також не можете seek(довільно змінити положення вказівника на файл) у труба, поки ви можете у звичайному файлі. Деякі команди можуть використовувати більш ефективний алгоритм, коли seek-ing у вхідному файлі можливий.


Я б сказав, що командний файл віддається перевазі команді <файл, оскільки команда може робити якийсь непослідовий доступ.
користувач606723

І що б заважало йому це робити <file? Ваша точка дійсна для використання імені вхідного файла для отримання жорсткого імені вихідного файлу, наприклад: gzip fileвиробляє file.gz.
alex

можливо я не розумію, як перенаправлення працює всередині. Скажімо, ми переспрямовуємо фільм на 12 ГБ в mplayer / vlc, а потім пропускаємо до кінця. Що саме відбудеться в цьому випадку?
user606723

1
Shell відкриває файл і розсилає підпроцес, який успадковує дескриптор файлу. Роздвоєний процес closes stdinі викликає dupдескриптор відкритого файлу, тому він замінює старий stdin(який у більшості випадків був якийсь тип). З точки зору програвача фільму, різниці між цим та відкриттям файлу немає за його ім'ям у сам гравець. Дескриптор файлу можна шукати в обох сценаріях, тому, коли ми переходимо до кінця, різниці, що визначаються користувачем, немає.
alex
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.