Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

почему глючит ls

60 views
Skip to first unread message

Melleus

unread,
Jan 21, 2016, 4:20:03 PM1/21/16
to
Не могу понять, что происходит.

1. Так - работает:

me@machine:~/Загрузки/ > ls 0*.pdf
0470568135.pdf 0521191130 2.pdf 055-059.pdf 05.pdf 065-067.pdf

2. А так - не работает:

me@machine:~/Загрузки/ > ls *.pdf
ls: неверный ключ — «��
По команде «ls --help» можно получить дополнительную информацию.

Что я делаю не так? Спасибо заранее.

Mikhail A Antonov

unread,
Jan 21, 2016, 4:40:03 PM1/21/16
to
22.01.2016 00:15, Melleus пишет:
а так?
ls -- *.pdf

--
Best regards,
Mikhail
-
WWW: http://www.antmix.ru/
XMPP: ant...@stopicq.ru

signature.asc

Melleus

unread,
Jan 21, 2016, 5:10:04 PM1/21/16
to
Mikhail A Antonov <mik...@antfam.ru> writes:

> а так?
> ls -- *.pdf

Так все прекрасно работает, правда не совсем понятно почему, в мане не
нашел такой опции. Спасибо огромное!

Vasily Ivanov

unread,
Jan 22, 2016, 1:10:03 AM1/22/16
to
On 2016-01-22 0004 (+0200), Melleus wrote:
>Mikhail A Antonov <mik...@antfam.ru> writes:
>
>> а так?
>> ls -- *.pdf
>
>Так все прекрасно работает, правда не совсем понятно почему, в мане не
>нашел такой опции.

Ноги растут из POSIX: http://pubs.opengroup.org/onlinepubs/9699919799/

Guideline 10:
The first -- argument that is not an option-argument should be
accepted as a delimiter indicating the end of options. Any following
arguments should be treated as operands, even if they begin with the
'-' character.

Вероятно, имеются файлы, имя которых начинается с '-'. При запуске с
*.pdf шелл разворачивает имена, и ls считает, что ему дают опцию
-somefile.pdf. Использование '-- ' позволяет обойти это.

Artem Chuprina

unread,
Jan 22, 2016, 1:20:02 AM1/22/16
to
Melleus -> debian-...@lists.debian.org @ Fri, 22 Jan 2016 00:04:07 +0200:

>> а так?
>> ls -- *.pdf

M> Так все прекрасно работает, правда не совсем понятно почему, в мане не
M> нашел такой опции. Спасибо огромное!

Это стандартная опция для всех команд, у которых GNU-like схема разбора
параметров. Означает "то, что дальше - не опции, даже если похоже на
них с виду".

* раскрывается ШЕЛЛОМ ДО того, как список файлов передается команде ls.
А зачем у тебя там файл, имя которого начинается с -, это уже даже не
к шеллу вопрос...

Vasiliy P. Melnik

unread,
Jan 22, 2016, 2:30:02 AM1/22/16
to
название файла видать какое-то такое нехорошее.

22 января 2016 г., 0:04 пользователь Melleus <mel...@openmailbox.org> написал:

yuri.n...@gmail.com

unread,
Jan 22, 2016, 2:40:03 AM1/22/16
to
Ну смотрите что происходит. Вместо *.pdf командный интерпретатор
подставляет имена файлов. Если какое-то имя начинается
с минус ('-'), то программа ls думает, что это ей ключик такой
дали и ругается. Два минуса означает, что список ключей закончился -
далее только файлы.
Такой поведение обычно для многих GNU программ (rm, mv ...)
Ю.

p.s. Шутка для начинающих сисадминов - завести файл с
именем '-rf' и пожаловаться сисадмину, что у вас есть файл
который с вашими правами не удаляется.

Victor Wagner

unread,
Jan 22, 2016, 3:50:02 AM1/22/16
to
On Fri, 22 Jan 2016 00:29:56 +0300
Mikhail A Antonov <mik...@antfam.ru> wrote:

> >
> > 2. А так - не работает:
> >
> > me@machine:~/Загрузки/ > ls *.pdf
> > ls: неверный ключ — «��
> > По команде «ls --help» можно получить дополнительную информацию.
> >
> > Что я делаю не так? Спасибо заранее.
> >
> а так?
> ls -- *.pdf

А еще можно ls ./*.pdf

Это сработает даже для программ, которые не понимают --

Oleksandr Gavenko

unread,
Jan 22, 2016, 5:10:04 AM1/22/16
to
On 2016-01-22, Vasiliy P. Melnik wrote:

> > а так?
> > ls -- *.pdf
>
> Так все прекрасно работает, правда не совсем понятно почему, в мане не
> нашел такой опции. Спасибо огромное!

Как писали ране не нашли потому что:

$ man 1 ls

SEE ALSO
Full documentation at: <http://www.gnu.org/software/coreutils/ls>
or available locally via: info '(coreutils) ls invocation'

$ info '(coreutils) Common options'

‘--’
Delimit the option list. Later arguments, if any, are treated as
operands even if they begin with ‘-’. For example, ‘sort -- -r’
reads from the file named ‘-r’.

и у Вас ls/cp/mv/etc из GNU coreutils.

Далее POSIX.1-2008:

Shell & Utilities

1.4 Utility Description Defaults

Default Behavior: When this section is listed as "None.", it means that the
implementation need not support any options. Standard utilities that do not
accept options, but that do accept operands, shall recognize "--" as a first
argument to be discarded.

The requirement for recognizing "--" is because conforming applications need
a way to shield their operands from any arbitrary options that the
implementation may provide as an extension. For example, if the standard
utility foo is listed as taking no options, and the application needed to
give it a pathname with a leading <hyphen>, it could safely do it as:

foo -- -myfile

Тут текст конечно с оговорками, без прямого указания как работать с "--", но
по собраной POSIX chm неудобно искать другие упоминания.

--
http://defun.work/

Oleksandr Gavenko

unread,
Jan 22, 2016, 5:20:03 AM1/22/16
to
On 2016-01-22, Victor Wagner wrote:

>> а так?
>> ls -- *.pdf
>
> А еще можно ls ./*.pdf
>
> Это сработает даже для программ, которые не понимают --

Добавлю что проблемы бывают не только в именах файлов, но и в патернах и
подпрограммах:

$ grep "-v" # плохо
$ grep "[-]v" # хорошо

Тут тот же трюк - изменить синтаксис (префикс), оставив семантику.

--
http://defun.work/

Victor Wagner

unread,
Jan 22, 2016, 6:30:03 AM1/22/16
to
On Fri, 22 Jan 2016 12:14:40 +0200
Oleksandr Gavenko <gave...@gmail.com> wrote:

> On 2016-01-22, Victor Wagner wrote:
>
> >> а так?
> >> ls -- *.pdf
> >
> > А еще можно ls ./*.pdf
> >
> > Это сработает даже для программ, которые не понимают --
>
> Добавлю что проблемы бывают не только в именах файлов, но и в
> патернах и подпрограммах:
>
> $ grep "-v" # плохо
> $ grep "[-]v" # хорошо

Вот в случае grep я как раз предпочитаю использовать ключик -e, который
указывает что следующий аргумент является регулярным выражением, а не
флагом.

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

Melleus

unread,
Jan 22, 2016, 10:50:03 AM1/22/16
to
Victor Wagner <vi...@wagner.pp.ru> writes:

> А еще можно ls ./*.pdf

Утащил себе в блокнот, спасибо.

Melleus

unread,
Jan 22, 2016, 11:00:03 AM1/22/16
to

Всем - огромное человеческое спасибо. Действительно, название одного из
файлов начиналось с дефиса. Вроде бы - мелочь, а какой пласт информации
поднялся. Вот уж действительно, система, которая мягко и эффективно
понуждает своих пользователей к мозговой деятельности. Даже если что-то
и не получается. Да еще и варианты возможны. Еще раз спасибо всем!

Tim Sattarov

unread,
Jan 22, 2016, 5:20:03 PM1/22/16
to
On 22/01/16 03:46 AM, Victor Wagner wrote:
> А еще можно ls ./*.pdf

а если в названии файла есть пробелы ?
что то вроде "Отчет -за-период.pdf"
или еще хуже
"Malicious File; rm -rf *.pdf"

хотя тут что то не так, мои тесты показывают, что по крайней мере у cat
и ls проблем с этим не возникает...

```
17:08 $ ls -l
total 4
-rw-r--r-- 1 tumyp tumyp 0 Jan 22 17:05 -A ;rm *
-rw-r--r-- 1 tumyp tumyp 5 Jan 22 17:00 malfile; ls -l .pdf
```

```
17:09 $ /bin/ls -l ./*
-rw-r--r-- 1 tumyp tumyp 0 Jan 22 17:05 ./-A ;rm *
-rw-r--r-- 1 tumyp tumyp 5 Jan 22 17:00 ./malfile; ls -l .pdf
```

Artem Chuprina

unread,
Jan 22, 2016, 9:10:03 PM1/22/16
to
Tim Sattarov -> debian-...@lists.debian.org @ Fri, 22 Jan 2016 17:10:39 -0500:

>> А еще можно ls ./*.pdf

TS> а если в названии файла есть пробелы ?
TS> что то вроде "Отчет -за-период.pdf"
TS> или еще хуже
TS> "Malicious File; rm -rf *.pdf"

TS> хотя тут что то не так,

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

Команда ls, как и все другие команды, кроме тех, у которых интерпретация
строк в аргументах явно прописана в документации, не интерпретируют
ничего в своих аргументах, кроме похожих на ключ (т.е. начинающихся с
-).

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

В результате проблеме просто взяться неоткуда.

В винде не так.

TS> мои тесты показывают, что по крайней мере у cat и ls проблем с этим
TS> не возникает...

TS> ```
TS> 17:08 $ ls -l
TS> total 4
TS> -rw-r--r-- 1 tumyp tumyp 0 Jan 22 17:05 -A ;rm *
TS> -rw-r--r-- 1 tumyp tumyp 5 Jan 22 17:00 malfile; ls -l .pdf
TS> ```

TS> ```
TS> 17:09 $ /bin/ls -l ./*
TS> -rw-r--r-- 1 tumyp tumyp 0 Jan 22 17:05 ./-A ;rm *
TS> -rw-r--r-- 1 tumyp tumyp 5 Jan 22 17:00 ./malfile; ls -l .pdf
TS> ```

dimas

unread,
Jan 23, 2016, 5:00:02 PM1/23/16
to
раз пошел такой разговор:

>00:47:41 024 /tmp/test$ touch "-l"
touch: неверный ключ — «l»
По команде «touch --help» можно получить дополнительную информацию.
>00:47:49 024 /tmp/test$ touch -- -l
>00:47:54 024 /tmp/test$ touch "aaa"
>00:48:01 024 /tmp/test$ ls
aaa -l
>00:48:06 024 /tmp/test$ ls *
-rw------- 1 dimas dimas 0 янв 24 00:48 aaa
>00:48:10 024 /tmp/test$ rm aaa
>00:48:28 024 /tmp/test$ ls
-l
>00:48:30 024 /tmp/test$ ls *
итого 0
-rw------- 1 dimas dimas 0 янв 24 00:47 -l
>00:48:34 024 /tmp/test$ rm *
rm: неверный ключ — «l»
Попробуйте «rm ./-l», чтобы удалить файл «-l».
По команде «rm --help» можно получить дополнительную информацию.
>00:48:41 024 /tmp/test$ rm ./-l

да уж, прикол... а кто-нибудь может объяснить, почему в случае с touch "-l"
аргумент в кавычках все равно парсится как ключ?

Alex Kicelew

unread,
Jan 23, 2016, 5:40:02 PM1/23/16
to
On 01/24/16 00:55, dimas wrote:
> да уж, прикол... а кто-нибудь может объяснить, почему в случае с touch "-l"
> аргумент в кавычках все равно парсится как ключ?

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

yuri.n...@gmail.com

unread,
Jan 24, 2016, 3:40:02 AM1/24/16
to
Могу еще добавить для тех кто С немножко знает.
Посмотрите
> man 3 getopt

В секции EXAMPLE есть работающие программы с примером
разбора аргументов.
На практике, обычно эти функции и используют для анализа
опций командной строки.
Можно скомпилировать, поиграться и разобраться,
что делает шелл и что видит программа на входе.

Ю.

Oleksandr Gavenko

unread,
Jan 24, 2016, 9:30:02 AM1/24/16
to
On 2016-01-23, dimas wrote:

> да уж, прикол... а кто-нибудь может объяснить, почему в случае с touch "-l"
> аргумент в кавычках все равно парсится как ключ?

Откройте POSIX:

http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
2. Shell Command Language

The shell operates according to the following general overview of
operations. The specific details are included in the cited sections of this
chapter.

The shell reads its input from a file (see sh), from the -c option or
from the system() and popen() functions defined in the System Interfaces
volume of IEEE Std 1003.1-2001. If the first line of a file of shell
commands starts with the characters "#!", the results are unspecified.

The shell breaks the input into tokens: words and operators; see Token
Recognition.

The shell parses the input into simple commands (see Simple Commands)
and compound commands (see Compound Commands).

The shell performs various expansions (separately) on different parts of
each command, resulting in a list of pathnames and fields to be treated
as a command and arguments; see Word Expansions.

The shell performs redirection (see Redirection) and removes redirection
operators and their operands from the parameter list.

The shell executes a function (see Function Definition Command),
built-in (see Special Built-In Utilities), executable file, or script,
giving the names of the arguments as positional parameters numbered 1 to
n, and the name of the command (or in the case of a function within a
script, the name of the script) as the positional parameter numbered 0
(see Command Search and Execution).

The shell optionally waits for the command to complete and collects the
exit status (see Exit Status for Commands).

Т.е. при разборе строки происходит несколько шагов. С ``touch "-l"`` мы на шаге:


The shell breaks the input into tokens: words and operators; see Token
Recognition.

Смотрим по ссылке:

2.3 Token Recognition

If the current character is backslash, single-quote, or double-quote (
'\', '", or ' )' and it is not quoted, it shall affect quoting for
subsequent characters up to the end of the quoted text. The rules for
quoting are as described in Quoting. During token recognition no
substitutions shall be actually performed, and the result token shall
contain exactly the characters that appear in the input (except for
<newline> joining), unmodified, including any embedded or enclosing quotes
or substitution operators, between the quote mark and the end of the
quoted text. The token shall not be delimited by the end of the quoted
field.

If the current character is an unquoted <blank>, any token containing the
previous character is delimited and the current character shall be
discarded.

If the previous character was part of a word, the current character shall
be appended to that word.

Вот и обьяснение. Кавычки попадают в shell, обрабатываются и не доходят до
команды. Т.е. кавычки - это особенность shell, команда вообще ни при чем.


В разных контекстах выполняются разные шаги. Стоит раз разобраться.

Например ``Parameter Expansion`` не делается в одинарных кавычках.

Для проверки на пустоту важно взять параметер в двойные кавычки. built-in Bash
test как то отрабатывает:

$ [ -z -a -z ]
$ x=
$ [ -z $x -a -z $x ]


В GNU coreutils это не срабатывает:

bash# /usr/bin/\[ -z -a -z ]
/usr/bin/[: extra argument ‘-z’

bash# /usr/bin/\[ -z $x -a -z $x ]
/usr/bin/[: extra argument ‘-z’

В FreeBSD sh также не позволяет:

$ [ -z -a -z ]
[: -a: unexpected operator
$ [ -z $x -a -z $x ]
[: -a: unexpected operator

Расширение Bash работает двояко:

$ [[ -z ]]
bash: unexpected argument `]]' to conditional unary operator
bash: syntax error near `]]'

тогда как это сработает:

bash# [[ -z $x ]]

Признаюсь что у меня нет 100% гарантии с обьяснения мануала почему оно
работает. Прямо так не сказано. bash(1):

[[ expression ]]

Return a status of 0 or 1 depending on the evaluation of the
conditional expression expression. Expressions are composed of the
primaries described below under CONDITIONAL EXPRESSIONS. Word
splitting and pathname expansion are not performed on the words
between the [[ and ]]; tilde expansion, parameter and variable
expansion, arithmetic expansion, command substitution, process
substitution, and quote removal are performed. Conditional operators
such as -f must be unquoted to be recog‐ nized as primaries.

See the description of the test builtin command (section SHELL BUILTIN
COMMANDS below) for the handling of parameters (i.e. missing
parameters).

Т.е. сделается пустая подстановка вместо $x, но место быдет считаться занятым
потому что не происходит Word splitting?

Переносимый синтаксис:

$ [ -z "$x" -a -z "$x" ]

Еще пример Bash расширения когда от контекста зависит какие шаги выбираются по
преобразованию строки:

$ [[ axa == *x* ]] && echo ok

Вспоминаем что в ``[[`` не делается pathname expansion и дополнительно:

When the == and != operators are used, the string to the right of the operator
is considered a pattern and matched according to the rules described below
under Pattern Matching, as if the extglob shell option were enabled.

Этим пользуюсь вместо:

case axa in *x*) echo ok;; esac

--
http://defun.work/

Alex Kuklin

unread,
Jan 24, 2016, 9:50:02 AM1/24/16
to
потому что есть файл, имя которого начинается с -.
писать ls -- *.pdf, -- прекращает обработку ключей.

Peter Pentchev

unread,
Jan 25, 2016, 5:20:02 AM1/25/16
to
Или pgrep.

Всего лучшего,
Петр

--
Peter Pentchev ro...@ringlet.net ro...@FreeBSD.org p...@storpool.com
PGP key: http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint 2EE7 A7A5 17FC 124C F115 C354 651E EFB0 2527 DF13
signature.asc

Tim Sattarov

unread,
Jan 28, 2016, 6:00:04 PM1/28/16
to
On 22/01/16 09:07 PM, Artem Chuprina wrote:
> Tim Sattarov -> debian-...@lists.debian.org @ Fri, 22 Jan 2016 17:10:39 -0500:
>
>
> TS> хотя тут что то не так,
>
> Тут как раз всё так. В смысле, компьютер работает правильно, а вот у
> тебя представление не вполне адекватное.
Ну уж прям и неадекватное ? :)
> Команда ls, как и все другие команды, кроме тех, у которых интерпретация
> строк в аргументах явно прописана в документации, не интерпретируют
> ничего в своих аргументах, кроме похожих на ключ (т.е. начинающихся с
> -).
>
> А шелл, раскрыв шаблон имени файла в список имен файлов, передает этот
> список команде (в данном случае ls) наиболее естественным образом -
> каждое имя файла отдельным аргументом.
>
> В результате проблеме просто взяться неоткуда.
>
> В винде не так.
>

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

Хорошего дня.
Тимур

Artem Chuprina

unread,
Jan 29, 2016, 1:20:03 AM1/29/16
to
Tim Sattarov -> debian-...@lists.debian.org @ Thu, 28 Jan 2016 17:54:32 -0500:

>> TS> хотя тут что то не так,
>>
>> Тут как раз всё так. В смысле, компьютер работает правильно, а вот у
>> тебя представление не вполне адекватное.

TS> Ну уж прям и неадекватное ? :)

НЕ ВПОЛНЕ адекватное. Ну, было. Сейчас уже не знаю.

>> Команда ls, как и все другие команды, кроме тех, у которых интерпретация
>> строк в аргументах явно прописана в документации, не интерпретируют
>> ничего в своих аргументах, кроме похожих на ключ (т.е. начинающихся с
>> -).
>>
>> А шелл, раскрыв шаблон имени файла в список имен файлов, передает этот
>> список команде (в данном случае ls) наиболее естественным образом -
>> каждое имя файла отдельным аргументом.
>>
>> В результате проблеме просто взяться неоткуда.
>>
>> В винде не так.
>>

TS> Еще раз подумав, я понял в чем тут дело.
TS> Спасибо за разъяснения, иногда не хватает полного понимания разбора
TS> аргументов
TS> и интерполяции переменных/параметров и получается некоторая каша в
TS> голове, полезно еще раз освежить и посмтреть по новому.
0 new messages