Не забудьте использовать
--
при передаче произвольных аргументов командам (или использовать перенаправления, где это возможно). Такsort -- "$f1"
или лучшеsort < "$f1"
вместоsort "$f1"
.
Почему это предпочтительно использовать --
и перенаправление?
Почему sort < "$f1"
предпочтительнее sort -- "$f1"
?
Почему sort -- "$f1"
предпочтительнее sort "$f1"
?
Спасибо.
Ответы:
терпит неудачу для значений
$f1
этого начала с-
или здесь для случая,sort
который начинается с+
(может иметь серьезные последствия для файла, называемого,-o/etc/passwd
например).(где
--
сигнализирует об окончании опций) решает большинство из этих проблем, но все еще не работает для вызываемого файла-
(которыйsort
вместо этого интерпретирует значение его стандартного ввода).Не имеет этих проблем.
Здесь это оболочка, которая открывает файл. Это также означает, что если файл не может быть открыт, вы также получите потенциально более полезное сообщение об ошибке (например, большинство оболочек будет указывать номер строки в скрипте), и сообщение об ошибке будет согласованным, если вы используете перенаправления, где это возможно, чтобы открыть файлы.
И в
(вопреки
sort -- "$f1" > out
), если"$f1"
не может быть открыт,out
не будет создан / усечен иsort
даже не запущен.Чтобы устранить возможную путаницу (следуя комментариям ниже), это не мешает команде
mmap()
вводить файл илиlseek()
вставлять в него (а этоsort
не так), если сам файл доступен для поиска. Единственное отличие состоит в том, что файл открывается ранее и в дескрипторе файла 0 оболочкой, а не позже командой, возможно, в другом дескрипторе файла. Команда все еще может искать / mmap, что fd 0, как ей угодно. Это не следует путать с тем,cat file | cmd
гдеcmd
stdin на этот раз является каналом, который не может быть преобразован / найден.источник
sort
последовательно читать данные, и вы не можетеmmap
файл. Хотяsort
проблем с этим может не быть, рассмотрим производительностьless <file
иless file
. В первом случаеless
необходимо сохранить все содержимое файла в памяти, во втором - разрешено читать только те части, которые ему нужны. А теперь представьте, чтоfile
это файл журнала объемом 100 ГБ ...less <file
все файлы хранятся в памяти, но это не обязательно, это недостаток меньше. Толькоcat file | less
вынужден. Проверьтеless /dev/fd/0 <f
, что не хранит файл в памяти, даже если он получает его на стандартный ввод. Это распространенное заблуждение, что стандартный ввод в Unix не поддается поиску. Фактически, это может быть доступно для поиска, в зависимости от типа файла.read()
считываете данные последовательно из файла, одновременно считываяmmap()
весь файл в память сразу?sort
POSIX. Но это правда, что это не всегда поддерживается.getopt()
функции C признает это значение аргумента--
. Но главное, что вы принимаете: обработка аргументов - это область отдельных программ, и не все относятся к ним--
особо.Проблема заключается в именах файлов, начинающихся с тире.
sort "$f1"
не работает, если значениеf1
начинается с,-
потому что команда будет интерпретировать значение как опцию. Обычно это приводит к ошибке, но может даже привести к дыре в безопасности . Сsort -- "$f1"
, двойной тир аргумент--
среднее «без вариантов за пределами этой точки» , поэтому значениеf1
не будет интерпретироваться как вариант. Но есть еще один крайний случай: если значениеf1
- тире и ничего больше, тогда это не опция, а аргумент-
, который означает «стандартный ввод» (потому что аргумент является входным файлом; для выходного файла это будет означать «стандартный вывод»).Использование перенаправления позволяет избежать всех этих ловушек.
Это относится к большинству команд, а не только
sort
.источник
sort < "$f1"
будет работать, если значение было равно-
? Это не в любой оболочке, которую я пробовал.seq 10 > -; sort -
сseq 10 > -; sort < -
.