LINUX.ORG.RU
ФорумTalks

Традиции командной строки


1

1

По традиции в командной строке спецсимволами (читай: дефисами) выделяются *ключевые слова* программы, а неключевые (типа имён файлов, регэкспов, чисел (в том числе отрицательных)) — нет. Хотя ежу ясно, что ввиду конечности ключевых слов, спецсимволами нужно маркировать *неключевые* слова.

# традиции
foo -key filename   # для защиты "от дурака" лучше даже `-key -- filename`
bar -key -- -42

# разум (тут в качестве спецсимвола взято двоеточие)
foo key :filename
bar key :-42

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

Перемещено post-factum из development



Последнее исправление: toady2 (всего исправлений: 4)
Ответ на: комментарий от www_linux_org_ru

«инфраструктура» не так уж и велика для каждого конкретного юзера

Инфраструктура это сотни утилит из base system и десятки разных более больших программ вроде gcc или git.

Саму base system по части управления файлами (файлами в архивах, файлами на удалённых носителях и т.п.), процессами и сетью можно вообще покрыть какой-то более sophisticated системой команд с меньшим количеством более абстрактных команд с более внятными именами (производными от обычных английских глаголов, например) и параметрами. Но это только на словах.

программы можно пропатчить

То как разбирают программы свои аргументы это личное дело этих программ и их авторов (стилевые предпочтения).

шелл может знать, какой тип аргументов нужен программе

Как он может это знать, учитывая, что программы разбирают аргументы ad-hoc? Разве что для программ которые используют getopt (прозрачным образом) это возможно.

quasimoto ★★★★
()
Ответ на: комментарий от invy
$ cd os/dragonfly
$ grep -rn "=.*getopt.*(" * | wc -l
816
$ cd ../inferno 
$ grep -rn "=.*getopt.*(" * | wc -l
3
$ cd ../../compiler/llvm
$ grep -rn "=.*getopt.*(" * | wc -l
0
$ cd ../clang         
$ grep -rn "=.*getopt.*(" * | wc -l
0
$ cd ../ghc                        
$ grep -rn "=.*getopt.*(" * | wc -l
0
$ cd ../sbcl                       
$ grep -rn "=.*getopt.*(" * | wc -l
0
$ cd ../node                       
$ grep -rn "=.*getopt.*(" * | wc -l
12

в node есть немножко :) Ну и в *BSD / coreutils, само собой. В остальном, почему-то редко getopt вижу.

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

я же сказал исходниик ls и grep, а не ...

ls? grep? ls и grep из *BSD? BSD (я привёл в пример dragonfly - форк FreeBSD) содержит, в том числе, ls и grep (негнутые ls и grep с негнутой getopt). ls и grep из coreutils?

quasimoto ★★★★
()

казалось бы причем тут поттеринг :)

вот оно брожение сверхценных идей:)

начни с алфавита он то уж явно криво сложился, как то без великой идеи в основе :)

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

начни с алфавита он то уж явно криво сложился, как то без великой идеи в основе :)

всегда в этом плане завидовал «иероглифистам» - длинна каждого имени минимальна :)

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

Алфавит слишком мелко. Пусть лучше принесёт ложбан в массы

kim-roader ★★
()
Ответ на: комментарий от quasimoto

На самом деле в дереве исходных текстов ghc (в ./utils и в ./nofib) используется getopt. Просто используется он из haskell, bash и perl программ, по этому твой шаблон ничего и не нашел.

kim-roader ★★
()

Как так получилось?

Да, как так получилось, что эта тема не дает тебе покоя?

no-such-file ★★★★★
()
Ответ на: комментарий от kim-roader

Просто используется он из haskell

Он не используется из haskell, System.Console.GetOpt это часть base - реимплементация сишных getopts, он используются в utils. Ещё у компилятора есть свои getOpts и getOptions - это относится к прагмам OPTIONS и OPTIONS_GHC.

quasimoto ★★★★
()

Отвечу разом всем тем, кого хватило только на аргументы вроде «аффтар мудаг», причём вопросом на вопрос — по-вашему, разработчики Cisco IOS тоже состоят из школьнегов-мудагов? Тамошние традиции ближе к «разумному» стилю из первого поста, нежели к традиционному в Unix. (Отличие лишь в том, что вместо двоеточия все неключевые слова предваряются специальным кл. словом, смысл которого ровно такой же как и у двоеточия: «следующий аргумент — не ключевое слово». То есть

foo bar file filename
вместо
foo bar :filename
.)

Кстати, в популярной в Unix программе ip (iproute2) используется стиль cisco. Не знаю, как народ, но лично я просто получаю удовлетворение, когда пишу команды для ip: выглядят почти как английский текст. В качестве приятного дополнения получаем лёгкое запоминание (man нужно прочитать один раз).

ip route default via 1.2.3.4
А вот написать ту же команду для старого «route» я уже сходу по памяти не могу. И куда деваются все эти приемущества от лаконичной записи команд типа `foo -aGzB -d 23 -q`, когда они предваряются `man foo`?!

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

Дорогой «ленарт»!

1. мне проще набрать

route add default gw 1.2.3.4

2. gw это и есть gw, а не какое то via что может означать и интерфейс (для чего нормальные люди пишут dev)... короче очередная сверхценная абстракция.

3. юникс-вей означает не скрывать абстракцией лежащий в основе системы принцип, а делать его доступным для пользователя без искажения логики это принципа вымученной ковырянием в носу (ну так же удобнее будет... наверное... это же очевидно в конце то концов!). Неоспоримый факт только логика функционирования системы, сделать ее доступной в простой команде минимально исказив ее реальный функционал залог успеха. И пользователи сами выработают культуру использования (вернее давно выработали), и не надо за них это делать.

PS Относится к юникс софту как будто важны написанные пусть даже сотни утилит, а не культура их использования и все то что настроено сверху этой системы это клинический идиотизм. И да, за разрушение экосистемы софта надо бить по рукам. Каждый балбес не задумываясь рассуждает как бы доставить гемороя миллионам людей в мире :(

PPS в конце концов эти поттерингоподобные прожекты читают дети :(

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

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

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

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

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

Если просмотреть «Unix Programmer's Manual November 3, 1971» от первой версии Юникса http://cm.bell-labs.com/cm/cs/who/dmr/1stEdman.html , то уже там команда «ls» имела опцию "-l". Поэтому нельзя сказать, что "-" это «новый» формат опций.

Но, возможно, что в той файловой системе имена файлов были только из букв и цифр.

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

> шелл может знать, какой тип аргументов нужен программе

Как он может это знать, учитывая, что программы разбирают аргументы ad-hoc?

он, представь себе, знает, только, как обычно в мире УГ, знает неполно и тормозно

информация о типах аргументов содержится в пакете bash-completion

(у меня на впс-ке один раз bash, запускаемый из РНР, стал запускаться секунд 5 — вылечилось удалением этого пакета)

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

Инфраструктура это сотни утилит из base system и десятки разных более больших программ вроде gcc или git.

инфраструктура — это только те проги, к которым *ты* сочиняешь или редактируешь аргументы

для меня это скажем wget и curl (использую почти все аргументы), и *небольшое* количество аргументов для perl tar g++ ssh/scp ls/cp/mv

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

на самом деле, конечно, список прог с небольшим реально используемым мной количеством опций приведен не полностью, но суммарно количество используемых мной ключей, наверно, не превосходит 200

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от x3al
for i in *.c; do cc "$i" -o "build-`date`/`echo $i|sed 's/\.c$//'`"; done

все эти кавычки нужны потому, что bash делает то, что ее не просят (а именно бьет на токены), примерно как microsoft word из мира унылого говна делает то, что его просят

должно быть так:

for :i in *.c; do cc $i -o :build-`date`/`echo $i|sed 's/\.c$//'`"; done

здесь:

1. $i не разбивается пробелами, а идет одним аргументом для сс

2. *.c не может быть ключом, поэтому двоеточие перед ним можно и нужно не ставить

3. *неизвестные* значения не могут быть ключами, т.е. перед $i двоеточие опять можно и нужно не ставить

если же нам надо что-то типа

gcc_options="$some_options $other_options $yet_another_options"
gcc $$gcc_options :hello.c o :hello

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

gcc_options="$some_options $other_options $yet_another_options"
gcc tokenize(gcc_options) :hello.c o :hello

p.s. но может можно сделать и еще лучше

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

сорри, забыл убрать один минус

в результате команда сократилась на 2 символа по отношению к bash:

было:

for i in *.c; do cc "$i" -o "build-`date`/`echo $i|sed 's/\.c$//'`"; done

стало:

for :i in *.c; do cc $i o :build-`date`/`echo $i|sed 's/\.c$//'`"; done
www_linux_org_ru ★★★★★
()
Ответ на: комментарий от x3al

или вот так, для более честного сравнения:

было:

for i in *.c; do cc $cc_options "$i" -o "build-`date`/`echo $i|sed 's/\.c$//'`"; done

стало:

for :i in *.c; do cc $$cc_options $i o :build-`date`/`echo $i|sed 's/\.c$//'`"; done

кстааааати: почему у тебя $i идет без кавычек как аргумент echo ?!

твой вариант, похоже, должен записываться так:

for i in *.c; do cc $cc_options "$i" -o "build-`date`/`echo \"$i\"|sed 's/\.c$//'`"; done
www_linux_org_ru ★★★★★
()
Ответ на: комментарий от toady2

сообщение от anonymous (17.05.2012 6:29:13) писал ты или нет?

на всякий случай повторю:

1. *прямые* ответы на вопросы там: http://www.stackoverflow.com

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

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

информация о типах аргументов содержится в пакете bash-completion

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

как обычно в мире УГ

$ man bash

...

BUGS
       It's too big and too slow.
quasimoto ★★★★
()

Насчёт лаконичности — шелл:

for f in $(seq 1 100) ; do wget -c "http://foo.bar/baz-$f.qux" ; done

хаскель:

for [1 .. 100] $ get C . fmt "http://foo.bar/baz-%i.qux"

форт:

"http://foo.bar/baz-%i.qux" fmt C get . 1 100 .. for

«обращённый» форт:

for .. 1 100 . get C fmt "http://foo.bar/baz-%i.qux"

с сахаром для URI и интерполяции:

for .. 1 100 . get C ://foo.bar/baz-%i.qux

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

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

:foo.bar/baz-%i.qux

:localhost/foo/bar/baz-%i.qux = :/foo/bar/baz-%i.qux

Bот так, наверно. И, в общем случае, get remote-file = move remote-file current-dir, где move — обобщение mv.

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

quasimoto ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.