Что означает такая команда, как cmd1 cmd2 cmd3 linux
Обновлено: 25.11.2024
Иногда бывает удобно фильтровать вывод команды (например, с помощью grep ), сохраняя при этом имена столбцов (первая строка). Как нам это сделать?
Одним из примеров этого может быть фильтрация вывода ps . В конце концов, что означает следующий вывод?
Было бы намного читабельнее, если бы вывод был таким:
Теперь правильный ответ на это:
Здесь tee берет переменное количество файлов для записи одного и того же вывода. Мы используем подстановку процесса (см. man bash ), чтобы заставить tee писать в именованные каналы, которые являются своего рода файлом. tee также выводит свой ввод на стандартный вывод, и мы подавляем это, перенаправляя его на /dev/null .
Поскольку список команд внутри процесса подстановки выполняется асинхронно, чтобы убедиться, что sed -n 1p запускается до grep logd , мы можем вставить sleep 0,1 с перед запуском grep logd . Это должно дать sed -n 1p достаточно времени, чтобы напечатать свою строку, и сделает вывод более надежным.
Интересно, что >(head -1) вместо >(sed -n 1p) не работает в Linux, потому что head закрывает свой стандартный ввод, как только считывает достаточно байтов для печати первого линия. В этот момент tee завершает работу со статусом выхода 141 (128 + 13 для SIGPIPE — объяснение см. в man bash и grep «Простые команды»). Вместо этого мы используем команду, которая гарантированно считывает весь вывод, поступающий в нее.
В оставшейся части этого поста я рассмотрю другое «решение» этой проблемы, использующее групповые команды, и покажу, почему оно неверно.
Неправильный ответ
Я прочитал комментарии под ответом на ServerFault на тему «Как выполнить grep вывода ps с заголовками», в которых предлагалось использовать ps -ef | < голова -1; журнал регистрации; > для решения этой проблемы (кстати, < cmd; cmd; > называется «групповой командой»). Если бы мы не знали из нашего предыдущего запуска, как будет выглядеть правильный вывод, это, похоже, сработало бы:
Но обратите внимание, что два из трех процессов отсутствуют. Что дает?
Суть в том, чтобы понять, что cmd1 | < cmd2; cmd3; > не обеспечивает копию стандартного вывода cmd1 в cmd2 и cmd3 (чтобы и cmd2, и cmd3 работали с одним и тем же вводом). Скорее, ввод является общим: все, что потребляется cmd2, больше недоступно для cmd3 .
Это очень легко доказать. Если мы заменим cmd2 чем-то, что потребляет весь ввод, например, grep (который должен потреблять каждую строку ввода в поисках совпадения), ввод для следующей команды должен быть пустым:
Действительно, мы видим, что wc -c имеет нулевые байты для работы.
Хорошо, вы можете подумать, но head -1 потребляет только первую строку (до первой новой строки) ввода, верно? Так почему же точно не ps -ef | < голова -1; журнал регистрации; >работа? Как оказалось, head читает больше, чем просто до первой новой строки:
Сколько он читает по умолчанию (я тестировал с помощью head из GNU coreutils 8.32)?
Он считывает первые 1024 байта, недоступные для других команд, следующих за ним. Это означает, что вам не следует полагаться на групповые команды для работы с одним входом.
Связывание команд в Linux позволяет нам выполнять несколько команд одновременно и напрямую через терминал. Это похоже на короткие сценарии оболочки, которые можно запускать напрямую через терминал. Цепочка команд Linux — это метод объединения нескольких команд таким образом, что каждая из них может выполняться последовательно в зависимости от оператора, который их разделяет, и эти операторы решают, как команды будут выполняться. Это позволяет нам запускать несколько команд последовательно или одновременно.
Операторы
Работа с операторами цепочки
<р>1. Оператор амперсанда (&): используется для запуска команды в фоновом режиме, чтобы можно было выполнять другие команды. Он отправляет процесс/скрипт/команду в фоновый режим, чтобы другие команды могли выполняться на переднем плане. Это повышает эффективность использования системных ресурсов и ускоряет выполнение скриптов. Это также называется созданием или разветвлением дочернего процесса на других языках программирования. Знак амперсанда можно использовать следующим образом: <р>2. Оператор AND (&&): Команда, следующая за этим оператором, будет выполняться только в том случае, если предшествующая ей команда будет успешно выполнена. Это полезно, когда мы хотим выполнить команду, если первая команда была выполнена успешно.<р>3. Оператор точки с запятой (;): используется для последовательного запуска нескольких команд за один раз. Но важно отметить, что команды, объединенные в цепочку оператором (;), всегда выполняются последовательно. Если две команды разделены оператором, то вторая команда всегда будет выполняться независимо от статуса выхода первой команды.В отличие от оператора амперсанда выполнение второй команды не зависит от статуса выхода первой команды. Даже если первая команда не будет успешно выполнена, т. е. статус выхода не равен нулю, вторая команда всегда будет выполняться.
Эти три команды будут выполняться последовательно. Но выполнение команды, предшествующей оператору ( ; ), будет выполнено, даже если выполнение первой команды не удалось.
<р>4. Логический оператор ИЛИ (||): команда, следующая за этим оператором, будет выполняться только в том случае, если выполнение предшествующей ей команды завершилось неудачно. Это очень похоже на оператор else. Если статус выполнения первой команды отличен от нуля, будет выполнена вторая команда.<р>5. Оператор трубопровода (|): этот оператор отправляет вывод первой команды на ввод второй команды.
В приведенной выше команде wc -l отображается количество строк. ls -l отображает список файлов в системе. Первая команда отображает количество файлов в каталоге. ls – l перечисляет имена файлов, и этот вывод отправляется следующей команде, которая подсчитывает количество строк во входных данных. В результате с помощью канала мы получаем количество файлов в каталоге.
<р>6. Оператор NOT (!) Используется для инвертирования выражения в command/. Мы можем использовать его для удаления всех файлов, кроме одного в каталоге.
Эта команда удалит все файлы в каталоге, кроме файла .txt. На изображении ниже мы создаем несколько файлов с помощью команды touch внутри каталога. ls показывает файлы в каталоге. Чтобы удалить все файлы, кроме «a.txt», мы используем! Оператор. Если мы снова перечислим файлы, мы увидим, что все файлы, кроме .txt, удалены.
<р>7. Операторы перенаправления (‘’,’>>’): этот оператор используется для перенаправления вывода команды или группы команд в поток или файл. Этот оператор может использоваться для перенаправления либо стандартного ввода, либо стандартного вывода, либо того и другого. Почти все команды принимают ввод с операторами перенаправления.
Первая команда создает файл с именем «имя_файла» (оператор перенаправления >> позволяет нам вводить данные в файл), а вторая команда сортирует содержимое файла. Обратитесь к изображению ниже, мы сначала создаем файл с числами, а затем используем эту команду. Это сортирует содержимое файлов.
<р>8. Операторы AND, OR как условие if-else: эта команда может использоваться как оператор if-else. Это комбинация логического И и логического ИЛИ.
Эта команда сначала проверит, существует ли каталог «ABC» или нет. Если он не существует, создается новый каталог, иначе «ABC» становится текущим каталогом. Обратитесь к изображению ниже, каталог с именем «ABC» не существует и, следовательно, он создан. Когда та же команда выполняется во второй раз, каталог уже существует, и, следовательно, «ABC» становится текущим каталогом.
<р>9. Оператор конкатенации (\): используется для объединения больших команд в несколько строк в оболочке. Это также улучшает читабельность для пользователей. Большая команда разбивается на несколько строк и, следовательно, используется для выполнения больших команд.
Откроется файл с именем text(1).
<р>10. Приоритет: эта команда используется для установки значения приоритета, чтобы несколько команд могли выполняться в заданном порядке.В первом случае, если первая команда выполнена успешно, вторая будет выполнена, а третья не будет выполнена. Но во втором случае будет выполнена третья команда, поскольку приоритет устанавливается с помощью оператора (). Обратитесь к изображению ниже: если каталог существует (первая команда), то текущий каталог становится PQR (вторая команда), но в первом случае третья команда не выполняется, а во втором случае, когда используется оператор приоритета, тогда третья команда также выполняется.
<р>11.Комбинированный оператор (<>): выполнение команды, следующей за этим оператором, зависит от выполнения первой команды. Набор команд, объединенных с помощью оператора <>, выполняется, когда предыдущая команда успешно выполнена.
В первом случае всегда будет напечатано приветствие. Если файл существует, команда будет выполнена, поскольку она предшествует оператору &&. Если мы хотим выполнить и вторую, и третью команды, только если файл существует, то мы используем операторы <> для объединения команд.
В чем разница между следующими методами объединения команд?
4 ответа 4
Предположим, что есть команда1 && команда2 .
В этом случае команда2 будет выполнена тогда и только тогда, когда команда1 вернет нулевой статус выхода.
<р>; это просто разделитель команд. Таким образом, команда2 будет выполнена независимо от того, что вернула команда1.Аналогично команда1 || Команда2 может использоваться для запуска команды2, только если команда1 вернула ненулевой статус выхода.
Обратите внимание, что возвращаемое значение полного выражения — это возвращаемое значение последней выполненной команды.
На самом деле странно... если команда1 возвращает ноль, то выполняется команда2? Говоря о ленивом вычислении, && не должен даже смотреть на второй аргумент, когда первый уже равен 0 - результат все равно будет 0.
@Konerak: в кодах выхода 0 указывает на успех или true, а все остальное — на false , так что это как бы наоборот по сравнению с «обычными» логическими значениями.
@hammar, это выглядит довольно неудачно. Более логичным выбором было бы 0 || next_step для обозначения успеха предыдущего шага в соответствии с ленивой оценкой логического или.
команда1; cmd2 выполняет cmd1, затем cmd2, несмотря ни на что. Это в точности эквивалентно размещению cmd1 и cmd2 в отдельных строках¹. Статус возврата этой составной команды такой же, как у cmd2 .
cmd1 && cmd2 выполняет cmd1 . Затем, если статус выхода cmd1 равен нулю, выполняется cmd2. Статус возврата этой составной команды такой же, как у cmd1, если он отличен от нуля (поэтому cmd2 не выполнялась), и у cmd2 в противном случае (если она выполнялась).
если cmd1; затем cmd2; fi в основном эквивалентен cmd1 && cmd2 . Основное отличие состоит в том, что версия с if возвращает 0, если cmd1 возвращает ненулевой статус.
Команда возвращает 0, чтобы указать на успех, и ненулевой код ошибки (от 1 до 255, обычно от 1 до 125, поскольку более высокие значения имеют другие значения) для обозначения ошибки. Таким образом, cmd1; cmd2 означает «выполнять эти команды последовательно, несмотря ни на что», тогда как cmd1 && cmd2 означает «выполнять эти команды, но немедленно останавливаться, если первая команда не удалась».
Вы можете указать оболочке перейти в режим «выход при ошибке», запустив set -e . В этом режиме оболочка завершает работу, как только любая команда возвращает ненулевой статус, за исключением условных конструкций (левая часть && или ||, часть условия if и while). Таким образом, при наборе -e , ; (или символ новой строки) фактически эквивалентен && ².
Мы не говорим здесь о ПВХ, но эти каналы командной строки не менее полезны и представляют огромную ценность для системных администраторов.
Опубликовано: 7 августа 2019 г. | Кен Хесс (Red Hat)
Мне жаль сообщать вам, но командная строка не исчезла вместе с динозаврами и не исчезла с дронтом или почтовым голубем. Командная строка Linux жива и здорова, и по-прежнему работает. Это эффективный способ быстрого сбора и обработки информации, создания новых сценариев и настройки систем.
Одним из самых мощных операторов оболочки является канал ( | ). Канал принимает выходные данные одной команды и использует их в качестве входных данных для другой. И вы не ограничены одной конвейерной командой — вы можете складывать их столько раз, сколько хотите, или до тех пор, пока не закончатся выходные данные или файловые дескрипторы.
Одним из основных назначений конвейера является фильтрация. Конвейер используется для фильтрации содержимого большого файла — например, для поиска определенной строки или слова. Именно поэтому наиболее популярное использование каналов включает команды grep и sort . Но вы не ограничены этими случаями. Вы можете передать вывод любой команде, которая принимает поток ввода. Давайте рассмотрим теоретический пример как иллюстрацию того, как работает этот процесс:
И cmd1, и cmd2 являются утилитами командной строки, которые выводят результаты на экран ( стандартный вывод ). Однако, когда вы передаете вывод одной команды другой, информация из cmd1 не выводит вывод на экран. Канал перенаправляет этот вывод в качестве ввода в cmd2 .
Примечание. Не путайте перенаправление канала ( | ) с перенаправлением файла ( > ) и ( ). (Пример перенаправления файла: cmd1 > файл или cmd1.) Перенаправление файла либо отправляет вывод в файл, а не на экран, либо извлекает ввод из файла.
Давайте рассмотрим несколько реальных примеров того, как работает конвейер.
Проверка сетевых карт
Допустим, вам нужно знать, имеет ли одна из ваших сетевых карт (NIC) IP-адрес, начинающийся с 192:
$ ifconfig | группа 192
inet 192.168.1.96 сетевая маска 255.255.255.0 широковещательная рассылка 192.168.1.255
Вы также можете узнать, какие активные сетевые карты у вас есть в системе, с помощью простого конвейера для grep :
$ ifconfig | ГРУП ВВЕРХ
enp0s3: flags=4163 mtu 1500
lo: flags=73 mtu 65536
Вы также можете найти "RUNNING" или "RUN", чтобы отобразить ту же информацию.
Проверка разрешений
Возможно, вы хотите узнать, сколько каталогов в /etc доступно для записи пользователю root:
$ sudo ls -lR | grep drwx
Результаты слишком длинные, чтобы перечислять их здесь, но, как видно из отображаемого списка, их много. Вам все еще нужно выяснить, сколько их, а визуальный подсчет займет много времени. Простой вариант — передать результаты вашей команды ls команде wc (счетчик слов):
$ sudo ls -lR | grep drwx | туалет -l
Переключатель -l отображает количество строк. Ваш счет может быть другим. Этот список взят из новой установки «Сервер RHEL 8 без графического интерфейса».
[Хотите попробовать Red Hat Enterprise Linux? Загрузите его сейчас бесплатно.]
Подсчет файлов
Вам не нужно постоянно использовать grep. Например, вы можете перечислить количество файлов в каталоге /etc следующим образом:
Опять же, ваши результаты могут выглядеть иначе, но вы знаете, что что-то не так, если команда возвращает небольшое количество файлов.
Идентификация процессов
Вы также можете выполнять сложные задачи с помощью конвейеров. Чтобы получить список идентификаторов процессов (PID) для всех процессов, связанных с systemd:
$ ps -ef | grep системный | awk '<напечатать $2>'
khess 17242 7505 0 09:40 pts/0 00:00:00 grep --color=auto systemd
Чтобы удалить эту запись из результатов, снова используйте оператор вертикальной черты:
$ ps -ef | grep системный | awk '<напечатать $2>' | grep -v grep
Переключатель -v указывает команде grep инвертировать или игнорировать строки, содержащие следующую за ней строку — в данном случае любую строку, содержащую слово "grep".
Сортировка результатов
Еще одно популярное использование оператора конвейера — сортировка результатов путем передачи их в команду sort. Допустим, вы хотите отсортировать список имен в contact.txt. Во-первых, давайте посмотрим на содержимое в том виде, в котором оно находится в файле перед сортировкой:
Боб Джонс
Лесли Смит
Дана Дэвид
Сьюзен Джи
Леонард Шмидт
Линда Грей
Терри Джонс
Колин Доу
>Дженни Кейс
Теперь отсортируйте список:
$ cat контакты.txt | сортировать
Боб Джонс
Колин Доу
Дана Дэвид
Дженни Кейс
Леонард Шмидт
Лесли Смит
Линда Грей
Сьюзен Джи
Терри Джонс
Вы можете изменить порядок сортировки с помощью ключа -r:
$ cat контакты.txt | сортировать -r
Терри Джонс
Сьюзан Джи
Линда Грей
Лесли Смит
Леонард Шмидт
Дженни Кейс
Дана Дэвид
Колин Доу
>Боб Джонс
Был ли результат для любого из них таким, как вы ожидали? По умолчанию команда sort выполняет словарную сортировку по первому слову или столбцу, поэтому Боб Джонс и Терри Джонс не перечислены друг за другом.
Вы можете выполнить сортировку по второму столбцу с помощью переключателя -k, указав столбец, по которому вы хотите выполнить сортировку, который в нашем списке является вторым столбцом:
$ cat контакты.txt | сортировать -k2
Дженни Кейс
Дана Дэвид
Колин Доу
Сьюзен Джи
Линда Грей
Боб Джонс
Терри Джонс
Леонард Шмидт
>Лесли Смит
Если у вас длинный список контактов и вы считаете, что этот список содержит повторяющиеся записи, вы можете передать свой список для сортировки, а затем uniq для удаления этих дубликатов:
$ cat контакты.txt | сортировать | уникальный
Эта команда отображает только уникальные записи, но не сохраняет результаты. Чтобы отсортировать файл, отфильтровать уникальные записи, а затем сохранить новый файл, используйте это:
$ cat контакты.txt | сортировать -k2 | уникальный > contact_list.txt
Помните, что оператор канала и оператор перенаправления файла делают разные вещи.
Подведение итогов
Теперь, когда вы ощутили всю мощь командной строки, как вы думаете, сможете ли вы справиться с такой ответственностью? Утилиты командной строки обладают большей гибкостью, чем их графические аналоги. А для некоторых задач нет графических эквивалентов.
Лучший способ изучить поведение командной строки — поэкспериментировать. Например, команда сортировки не делала то, что вы думали, пока не изучили ее подробнее. Не забудьте использовать мощь своих справочных ( man ) страниц, чтобы найти те «скрытые» секретные переключатели и параметры, которые превращают разочарование командной строки в успех командной строки.
В различных вариантах оболочки используются определенные символы (называемые метасимволами), которые имеют особое (или зарезервированное) значение. Дополнительные символы имеют особое значение при использовании в том, что Linux называет регулярными выражениями. И просто чтобы сделать вещи интересными, некоторые символы могут использоваться в обеих этих ситуациях и могут иметь разные значения.
В следующей таблице перечислены некоторые из наиболее распространенных метасимволов
подстановочный знак для чего угодно; нет никаких ограничений на такие вещи, как количество символов или какие символы (помимо того, что называется специальными символами и описанными здесь метасимволами) можно вставлять вместо *; например, вы можете отобразить все файлы данных DigitalMicrograph в текущей области с помощью
подстановочный знак для одного символа; нет ограничений на то, какие символы (кроме специальных символов и метасимволов) можно вставлять вместо ?; например, вы можете увидеть первые изображения в записанной числовой последовательности, используя
разделитель для диапазона односимвольных подстановочных знаков; например, если вы хотите вывести список изображений только из числового ряда, в котором интересующие вас файлы находятся в диапазоне от 140 до 179, вы можете использовать эту команду
разделители [ ] говорят: «замените этот символ на 4, или 5, или 6, или 7, и никак иначе» (и, как показано во втором примере выше, непрерывный диапазон можно указать, используя начало и конец диапазона с помощью тире ("-") между ними)
Вы также можете искать определенные буквы или алфавитные области букв, используя [ ]; команда
отображает все файлы, начинающиеся с заглавных букв, пока
покажет все файлы, начинающиеся с буквы (в отличие от цифры или другого символа, и имейте в виду, что [a-Z] вообще не работает!); наконец,
отображает все файлы, которые начинаются с букв A, C, F или x и заканчиваются четным числом
ПРИМЕЧАНИЕ: для понимания linux в целом и использования этих разделителей и подстановочных знаков чрезвычайно полезно прочитать о том, что linux называет регулярными выражениями. Например, в большинстве книг по Linux есть главы, посвященные тому, что они называют «сопоставлением с образцом» или «регулярными выражениями». Некоторые особенно полезные ресурсы: книги O'Reilly Media Sed & Awk и Mastering Regular Expressions (и карманные справочники O'Reilly по обоим).
| символ (называемый "канал") используется для конвейерной обработки команд, что означает, что вывод одной команды становится вводом для следующей команды
точка с запятой (;) – это "разделитель команд", который позволяет вводить последовательность команд в одну командную строку; это сильно отличается от конвейера тем, что объединенные вместе команды не зависят друг от друга для ввода
например, если вы активно работаете в одной области компьютера, но хотите переместиться в другое место и посмотреть, как много было сделано в этой области, вы можете составить ряд команд, которые сделают это и вернуть вас в исходное местоположение:
поскольку эта команда будет храниться в «истории» вашего терминала, будет легко вызывать эту «однострочную команду» всякий раз, когда вы хотите изучить, что произошло в области ProjectX (т.е., вспомнить эту единственную строку проще, чем вспомнить или повторно ввести три отдельные команды)
амперсанд (&) заставляет команду выполняться в «фоновом режиме» оболочки (это означает, что пользователь по-прежнему имеет доступ к интерактивной оболочке); например, если вы запустите графический текстовый редактор из командной строки без использования &, редактор запустится, но ваш терминал будет неактивен, пока вы не выйдете из редактора; вместо этого редактор следует запустить и запустить в фоновом режиме, используя следующий синтаксис:
или в существующий файл с помощью
во втором примере не имеет значения, существует ли oldFile или нет: команда перенаправления ">>" при необходимости создаст файл, но добавит его к существующему файлу; если используется команда перенаправления ">", файл всегда будет новым, а существующий файл с таким же именем будет перезаписан (и потерян)
ПРИМЕЧАНИЕ: каждая оболочка имеет свой синтаксис для одновременного перенаправления stdout и stderr в разные места или объединения stdout и stderr в один поток, который направляется в одно место
Обещание
Copyright © 2015 The Trustees of Indiana University, Жалобы на нарушение авторских прав
Читайте также: