LINUX.ORG.RU

Команда cut в bash

 , , ,


0

1

Недавно узнал, что команды:

сut -d. -f1

и

cut -d "." -f 1

равнозначны. Результат выполнения будет одинаковым, без всяких ошибок.

Для меня лично это было открытием, потому что я привык к тому, что пробел ставится после любой опции, если там один дефис. Например,

# command --option="value", если двойной дефис
command -o "value"

Даже в мыслях не предполагал, что может быть запись типа

command -ovalue

Это некое исключение в bash или это нормальный синтаксис для всех команд? Какие ещё подобные исключения вы можете привести, где после опции с одним дефисом не стоит пробел и сразу идёт значение опции?

И второй вопрос: к какому варианту в cut лучше привыкнуть сразу? К первому или второму? ИИ спрашивал, рекомендует вариант с пробелами (и кавычками, обязательно), но пишет, что оба варианта дадут одинаковые результаты выполнения и взаимозаменяемы.

★★★★★

Последнее исправление: Desmond_Hume (всего исправлений: 6)

Ну как можно?! Пять звёзд, а при этом не в курсе походу что такое баш.

cut это не команда баша, это программа. Каждая программа может устанавливать свои правила парсинга аргументов, и шелл (баш - это ОДИН из шеллов, но далеко не единственный) тут ни при чём. Впрочем, поскольку cut это часть пакета утилит GNU coreutils то правила парсинга аргументов у него похожие как у остальных GNU coreutils (например echo, ls или mv).

Конкретно по твоему вопросу - если опция с одним дефисом и из одной буквы, и ей нужен аргумент, то она обычно принимает его и без пробела.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)

Встроенной какой-то либы нет для парсинга аргументов командной строки. Просто так принято, что с - начинается имя, а далее через = или следующим аргументом идет значение. Для многих «стандартных» утилит применим краткий синтаксис -[a-z]<значение>, но это на усмотрение авторов, а им никто не мешает сделать так как взбредет в голову. Это не краткий синтаксис. Обработка аргументов уникальная для каждой утилиты

rtxtxtrx ★★
()
Последнее исправление: rtxtxtrx (всего исправлений: 1)

Это некое исключение в bash или это нормальный синтаксис для всех команд?

Нормальный в общем вроде, но иногда бывает, что какая-то программа не понимает, а так да, например

ping -c3
tail -n1

и тд.

papin-aziat ★★★★★
()
Ответ на: комментарий от papin-aziat
watch -n3 ls

Попробовал сейчас, реально работает. Сижу с глазами-чашками. Вопрос закрыт, это нормальный синтаксис, значит … придётся привыкать.

Desmond_Hume ★★★★★
() автор топика

Это некое исключение в bash или это нормальный синтаксис для всех команд?

bash тут не причем. Все зависит от конкретных команд, точнее какой парсер параметров командной строки они используют. Например cut и прочие команды из coreutils используют GNU getopt. В этих библиотечных функциях как раз поддерживается синтаксис без пробела после имени опции. Негнутые программы могут использовать другие библиотеки или вообще самописные парсеры, которые могут требовать обязательный пробел после имени опции. В общем it depends.

Какие ещё подобные исключения вы можете привести, где после опции с одним дефисом не стоит пробел и сразу идёт значение опции?

gcc hello.c -O2 -I/usr/local/include -ohello

И второй вопрос: к какому варианту в cut лучше привыкнуть сразу? К первому или второму?

По мне так читабельнее первый вариант с пробелом. А вообще почитай Google Shell Style Guide. Там в примерах видно, где лучше использовать пробелы, где ставить кавычки и т.д.

archie
()
Ответ на: комментарий от Desmond_Hume

Подстава в твоём случае скорее может скрываться не в том, что такое cut и как он себя ведёт, а не окажется ли неэкранированный символ специальным для баша в коде сut -d. -f1 😀

papin-aziat ★★★★★
()
Ответ на: комментарий от archie

А, даже так. Тогда лучше с пробелами привыкнуть, чтобы сработало и там, и там. Но это всё, конечно, разрыв шаблона, непривычно. Увидел где-то на форуме такую запись и ещё удивился, что никто не поправляет человека, что забыл пробелы поставить))

Desmond_Hume ★★★★★
() автор топика

А ещё такой прикол есть: если при вызове sed’а соединить опции -i и -e <pattern> в слитное -ie <pattern>, то опция -e, в добавок к своему нормальному значению, сработает ещё и как аргумент для -i (т.е. как если бы было написано -i e -e <pattern>), что приведёт к созданию файлов с буквой «e» на конце вместо изменения существующих.

annulen ★★★★★
()
Ответ на: комментарий от papin-aziat

Не, мне с пробелами больше нравится. Это выглядит «по-человечески», не сливается визуально. Меня мантра Python научила наглядности в коде, пускай даже долго печатать.

Desmond_Hume ★★★★★
() автор топика
Последнее исправление: Desmond_Hume (всего исправлений: 1)

Это можно сказать стандартный синтаксис для всех команд которые обрабатываются через гнутый getopt_long . Я тоже в своё время на это наткнулся случайно, но ни в одном мане я про это не встречал упоминаний. Т.е. стандарт де факто, но молчаливый. +)

В скриптах пишу по человечески, в командной строке иногда так.

vtVitus ★★★★★
()
Последнее исправление: vtVitus (всего исправлений: 1)
Ответ на: комментарий от vtVitus

Вот именно! Читаю man’ы, но там про такой вариант записи нет нигде. Возможно, один раз где-то и видел, но подумал, что это ошибка, опечатка, т.к. пояснений к этому не было.

Desmond_Hume ★★★★★
() автор топика
Ответ на: комментарий от Desmond_Hume

Ну, тут как бы уже этакие привычные выражения наблюдаются в скриптах, например мало кто напишет echo >foo, как-то некрасиво, но все пишут >/dev/null. И когда вырисовывается длинная спагеттина, то всякие -n1 и -с3 очень даже в тему оказываются. Но я не програмист, так, реплика из зала.

papin-aziat ★★★★★
()
Ответ на: комментарий от papin-aziat

Такие спагеттины можно заворачивать в пельменно-переменную шаурму, хотя если спагеттина очень длинная, то даже с переменными это будет взрывом на макаронной фабрике.

Desmond_Hume ★★★★★
() автор топика
Ответ на: комментарий от Desmond_Hume

Увидел где-то на форуме такую запись и ещё удивился, что никто не поправляет человека, что забыл пробелы поставить))

Хехе, никогда не понимал этой кулхацкерской экономии на пробелах. Я всегда ставлю пробелы после опции, кроме некоторых программ, у которых в манах опции пишутся без пробела, ну и соответственно все в интернетах тоже пишут без пробела. Однобуквенные опции использую только в самых общепринятых командах типа cp, mkdir, grep и т.д. В прочих командах стараюсь использовать длинные опции типа --option-name=value. Очень помогает, когда надо через полгода подправить уже написанный скрипт и ты уже в упор не помнишь, что делали всякие флаги -b, -i, -t

archie
()
Ответ на: комментарий от papin-aziat

но все пишут >/dev/null

Не ври, я пробел ставлю, без пробела и /dev/null тоже некрасиво. А вот в опциях, где можно, не ставлю.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

Хорошо, уточню. Говоря о bash, подразумеваю shell, и наоборот. Везде так обычно пишут. Да, формально это не так и неправильно. Это как про linux’ы на форумах и в жизни говорят, будто это операционная система, а на самом делел это просто ядро операционной системы, не более.

Desmond_Hume ★★★★★
() автор топика

Можно и без пробела, но надо учитывать, что это не универсально и есть утилиты, которые используют одинарный дефис перед параметром. Например magick (из пакета ImageMagick):

magick -list Kernel
magick --list Kernel  # Ошибка
magick -listKernel    # Ошибка
magick list Kernel    # Ошибка
dmitry237 ★★★★
()
Ответ на: комментарий от Desmond_Hume

Это плохая привычка, потому что шеллы бывают разные, а баш это линуксизм вообще, в BSD его обычно нет например. Шелл без уточнений это POSIX шелл /bin/sh.

И второе, ещё раз, cut это не команда никакого шелла, это программа. Это точно так же как сказать что firefox это команда шелла.

firkax ★★★★★
()
Ответ на: комментарий от firkax

То есть, bash не воспринимает cut как команду? А как он её тогда интерпретирует? В широком смысле слова те же самые фукнции можно воспринимать как команды, хотя это «пачка» команд .. мне кажется, это всё словоблудие, которое может привести в никуда. Вопрос большинству в треде оказался понятен, несмотря на моё косноязычие (тут не спорю).

Desmond_Hume ★★★★★
() автор топика
Ответ на: комментарий от Desmond_Hume

Для меня, простого юзверя, пока ещё нет разницы между внешними программами, встроенными и функциями, но может кто на пальцах объяснит, почему мы должны знать разницу.

papin-aziat ★★★★★
()
Ответ на: комментарий от papin-aziat

Именно. Команда или программа. Firefox - тоже может быть командой, командой выполнить целую простыню кода … я просто всё это логически масштабирую. Вот, например, с linux’ом так не получится. Хоть ты тресни, ядро - это не операционная система, а операционная система - это не ядро. Хотя … если опять же масштабировать в микромир, может, как раз ядро будет микросистемой (задумался).

Desmond_Hume ★★★★★
() автор топика
Ответ на: комментарий от Desmond_Hume

Firefox - тоже может быть командой, командой выполнить целую простыню кода

Пожалуйста, в федора-шапках так:

$ file /usr/bin/firefox 
/usr/bin/firefox: Bourne-Again shell script, ASCII text executable
papin-aziat ★★★★★
()
Ответ на: комментарий от Desmond_Hume

Он ищет бинарник с названием cut где-нить в $PATH. В этом бинарнике может быть, в общем случае, что угодно, хоть патч Бармина, башу всё равно.

Вопрос большинству в треде оказался понятен, несмотря на моё косноязычие (тут не спорю).

Вопрос то и мне понятен (и я на него даже ответил сразу).

firkax ★★★★★
()
Ответ на: комментарий от papin-aziat

Нет, не считаю /dev/null чем-то особенным в этих редиректах. А третий вариант вообще не использую, понятнее так: >> /dev/null 2>&1

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от papin-aziat

Он не прав?)) Но если поставить вопрос по-другому, то да, конечно же, операционная система без ядра быть не может, а если и может, то получится монстр как в фильме «Субстанция» (2024). А вот ядро без операционной системы, возможно и сможет, хотя тут сомнения. Зачем ядро само по себе, само в себе? Ядро это некий набор инструкций для аппаратной части компа, его устройств… по сути, «система» нужна для того, чтобы человек мог воспользоваться комфортно компьютером. Технически, если знать код ядра, можно и без системы, наверное, взаимодействовать с аппаратам, но это будет хардкор, на который не согласятся даже бывалые программисты.

Desmond_Hume ★★★★★
() автор топика
Ответ на: комментарий от Desmond_Hume

Ты хочешь дать наиболее общее определение, но это порой сделать крайне сложно или просто получится громоздко, поэтому проще дать определение с одного, актуального на данный момент для разговора или ЦА, аспекта.

papin-aziat ★★★★★
()

Не знаю ответа на твои вопросы, но в своих программах хорошо делать опции d и d1, обе с опциональными параметрами, типа d 1 и d1 1, естественно делающие совершенно разное

shimshimshim
()
Последнее исправление: shimshimshim (всего исправлений: 1)
Ответ на: комментарий от papin-aziat

Для меня, простого юзверя, пока ещё нет разницы между внешними программами, встроенными и функциями, но может кто на пальцах объяснит, почему мы должны знать разницу.

Разница возникает, когда нужно разобраться, почему поведение именно такое, какое есть, и чей код менять, чтобы оно изменилось. Ещё разница возникает при переходе с одного шелла на другой.

Допустим, у нас «команда» сut -d. -f1, и выполняем мы её в bash.

  1. Если cut — это built-in, то bash полностью ответственен за то, как интерпретируются аргументы. В другом шелле такого built-in’а вполне может не быть.
  2. Если это функция, то где-то в profile был засорсен файл с её кодом. bash передаст cut функции аргументы «-d.» и «-f1», а что будет дальше, определяет кодом функции, который можно изменить. Для другого шелла функцию, возможно, придётся переписывать.
  3. Если cut это программа, то bash форкается, находит бинарник в PATH, и запускает его с argv из трёх строк: «cut», «-d.», «-f1». Что происходит дальше уже полностью зависит от реализации бинарника. В другом шелле всё будет работать точно так же. Кроме того, это единственный вариант, где есть fork, т.е. самый медленный и потребляющий больше памяти (если это вдруг кому-то важно).
annulen ★★★★★
()
Ответ на: комментарий от Desmond_Hume

Ядро это некий набор инструкций для аппаратной части компа, его устройств… по сути, «система» нужна для того, чтобы человек мог воспользоваться комфортно компьютером.

«Воспользоваться комфортно компьютером» может означать просто запустить нужную программу и получить результат. А ядро Linux вполне способно выполнять программы самостоятельно, ему не нужны никакие юзерспейс-компоненты для этого. Кроме того, у Linux есть стабильный ABI/ABI, позволяющий влёгкую запускать программы 20-летней давности, чего нельзя сказать про GNU/Linux.

Так что Linux это ОС, просто довольно ограниченная в функциональности

annulen ★★★★★
()
Ответ на: комментарий от annulen

Кроме того, это единственный вариант, где есть fork, т.е. самый медленный и потребляющий больше памяти (если это вдруг кому-то важно).

Думаю, можно забыть на современных домашних компах последней пары десятилетий.

Спасибо за текст, но я пока так и не вижу солидной причины, чтобы регулярно использовать type, whatis, whereis, как рекомендуют (не дорос, наверное, ещё).

papin-aziat ★★★★★
()
Ответ на: комментарий от futurama

Если бы эта фича работала стабильно, можно было бы пользоваться без проблем. Но там есть нюансы в этой «склейке», иногда она не работает или работает не так, как ожидал пользователь.

Да, понятно, такие частые команды как ls -lah, df -hT и проч., что иногда приходится выполнять по 20-30 раз в день, можно писать в склейке, потому что сотни раз это всё перепробовано и поведение командной строки прогнозируемо.

Лично я за пробелы и python-дзен, кроме очевидных случаев как выше. Когда вслепую bashишь как бог 10-щупальцевым методом, это не проблема напечатать лишний пробел.

Desmond_Hume ★★★★★
() автор топика
Последнее исправление: Desmond_Hume (всего исправлений: 2)
Ответ на: комментарий от firkax

И второе, ещё раз, cut это не команда никакого шелла, это программа.

И всё-таки это именно команда, как и любая программа может быть командой. Команда - это указание, требование выполнить определённую инструкцию. В армии - это требование действия по уставу, к примеру. Устав - имеется в виду обобщение всего и устава, и конкретных приказов, методик и т.д. Суть - одинаковая. Просто в контексте армии своя специфика. Вот что ответил ИИ про «что такое cut в bash»:

Команда cut в Bash

Команда cut в оболочке Bash используется для извлечения определенных частей (столбцов) из текстовых файлов или стандартного ввода. Она работает, разбивая строки на поля, разделенные разделителями, и затем извлекает указанные поля.

Синтаксис:

cut [OPTIONS] [FILE]...

и т.д.

Естественно, что команда не может быть командой сама по себе. Любая команда - это инструкция, требование, указание на, ссылка для выполнения алгоритма. Любая программа - это алгоритм. Теорема доказана.

Desmond_Hume ★★★★★
() автор топика
Ответ на: комментарий от Desmond_Hume

Тут читать надо не «cut это не команда», а «cut это не команда никакого шелла, это программа».

Что в твоем первом сообщении, что в цитате утверждается что «это команда оболочки баш», что не так, это отдельная программа не имеющая отношения к башу.

Разницы для обывателя нет, но это выдает некомпетентность автора статьи (или это какой-то чат гпт глючит).

В баше есть встроенные команды и в некоторых случаях важно знать что перед тобой, команда оболочки или программа.

masa
()
Ответ на: комментарий от masa

А баш это и есть шелл, Bourne Again SHell. Ой, ладно. Тема закрыта. Я никогда не откажусь от мысли, что это всё команды, если применительно к командному интерпретатору. По отдельности - это да, всё программы, почти без исключения, потому что всё есть код, как ни крути. Просто уже смешно это всё обсуждать. Любой школьник, по-моему знает, что и bash, и сut написаны на С. И с этой позиции - они все программы, а никакие не шеллы там и проч.))) Спросил, называется …ахаха.

Desmond_Hume ★★★★★
() автор топика
Последнее исправление: Desmond_Hume (всего исправлений: 1)
Ответ на: комментарий от Desmond_Hume

Вот что ответил ИИ

Не надо это читать, сразу в мусорку.

И всё-таки это именно команда, как и любая программа может быть командой. Команда - это указание, требование выполнить определённую инструкцию

Хорошо. cut это команда шеллу найти бинарник с названием «cut» где-то в $PATH и запустить его, передав ему все аргументы. Либо, если бинарника не найдётся, вывести сообщение об ошибке. Что это за бинарник, зачем он нужен и какие у него аргументы - шеллу всё равно, его задача только передать управление.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)

к какому варианту в cut лучше привыкнуть сразу? К первому или второму?

У тебя уже сложилась очень хорошая привычка, придерживайся её, так ты гарантируешь себе то что у тебя всё всегда просто будет работать.

В чём суть вот такое

  • appname -axFfc -w800 -h600

бывает и часто, но это только если об этом специально позаботились, далеко не все так умеют или позволяют произвольно склеивать.
Часто тоже самое требуется записывать так

  • appname -a -x -F -f -c -w 800 -h 600

и это тот случай когда аргументы это просто аргументы, такое будет работать всегда и везде если у программы есть аргументы. Да, более размашисто, зато отражает то что действительно происходит при передаче аргументов.

Никто не мешает пользоваться и тем и тем, особенно в гнутых утилитах где всё предусмотрено для сокращённой записи. Но если появляются сомнения открой man или –help то лучше написать раздельно.

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от Radjah

Как с пайпами делают, ставят в начало строки, кстати, как-то не очень на мой вкус, в результате понимаешь, что выхлоп перенаправляется, только на следующей строке.

papin-aziat ★★★★★
()