Если оболочку просят выполнить, вероятно, бесполезную ( или частично бесполезную ) команду, о которой известно, что она завершается, например cat hugeregularfile.txt > /dev/null
, может ли она пропустить выполнение этой команды ( или выполнить, скажем, более дешевый эквивалент touch -a hugeregularfile.txt
)?
В более общем смысле, похожа ли оболочка на компиляторы C в том, что она может выполнять любое преобразование исходного кода, если наблюдаемое извне поведение выглядит так, как если бы его анализировала абстрактная машина?
РЕДАКТИРОВАТЬ
Nota Bene: У моего вопроса, который был задан изначально, был заголовок, в котором спрашивалось, разрешена ли оболочка для выполнения этих оптимизаций, а не должна ли она или даже существуют ли реализации, которые могут их выполнять. Я интересуюсь теорией больше, чем практикой, хотя оба приветствуются.
cat
он имеет большое значение. Оболочка может узнать, что файл является устройством, но он не обязательно должен быть надежным.wc
, например). Но, насколько мне известно, POSIX не занимает позицию по оптимизации оболочки; Или это?ksh
. Как будто они говорят не отдельный процесс, а среду оболочки, позволяющую оптимизировать сохранение ветвлений.Ответы:
Нет, это была бы плохая идея.
cat hugeregularfile.txt > /dev/null
иtouch -a hugeregularfile.txt
не одинаковы.cat
прочитает весь файл, даже если вы перенаправите вывод в/dev/null
. И чтение всего файла может быть именно тем, что вы хотите. Например, для того, чтобы кэшировать его, чтобы последующее чтение было значительно быстрее. Снаряд не может знать ваше намерение.Точно так же компилятор C никогда не оптимизирует чтение файла, даже если вы не смотрите на то, что читаете.
источник
true
иfalse
) есть потенциальные побочные эффекты, и побочные эффекты - почти всегда точка вызова команды. Оболочка не может знать эти побочные эффекты заранее (например, для внешних программcat
) без решения проблемы остановки. Так что это по праву не пытается, и предполагает, что вы имели в виду то, что сказали.cat
. На самом деле,cat
можно сделать что угодно, от форматирования жесткого диска до загрузки Интернета.true
иfalse
поставил$?
.cat
и/dev/null
имеют типичные значения , но они не гарантированы вести себя таким образом. Чтобы выполнить оптимизацию, гарантируя отсутствие изменений в ожидаемом поведении, оптимизация может быть разрешена только с использованием конструкций, реализованных в самой оболочке, а не вещей, найденных в среде выполнения ... независимо от того, насколько интуитивно понятны их имена.Нет, поскольку
/dev/null
это просто имя, которое можно использовать для любого другого устройства или для файла, отличного от того, что «обычно» является приемником данных.Таким образом, оболочка (или любая другая программа) понятия не имеет, основываясь на названии, является ли файл который она пишет, что-то «по-настоящему» с данными. Есть AFAIK, также нет системных вызовов, которые может выполнить программа оболочки, чтобы определить, что, например, дескриптор файла на самом деле ничего не делает.
Ваше сравнение с оптимизацией удаленного кода в программе на C не работает, поскольку у оболочки нет общего обзора, который есть у компилятора C над частью исходного кода. Оболочка не знает достаточно о том,
/dev/null
чтобы оптимизировать ваш пример, больше похоже на то, что компилятор C не знает достаточно о коде в вызове функции, на который он динамически ссылается, чтобы не делать вызов.источник
/dev/null
специально, иногда. Встроенная команда , которая имеет свой стандартный вывод направлена/dev/null
, напримерecho foo >/dev/null
, не приведет ни запись делаются для/dev/null
. Он не делает ничего особенного, если он вызывает не встроенную команду (например,cat file >/dev/null
).cat
может быть и что-то еще. Все остальное на самом деле./dev/null
это одна из очень немногих стандартных путей , а также/dev/tty
,/dev/console
,/tmp
,/dev/
и/
.cat
является встроенным ksh93 (не включен, если вы не вставили/opt/ast/bin
ранее/bin
(или там, гдеcat
это доступно) в$PATH
). И да, хотяcat file > /dev/null
с помощью этого встроенногоread
содержимого выполняется его содержимоеfile
, оно не записывает его в / dev / null (хотя оно открывается и создает его).Он не будет оптимизировать выполнение команд (и вы уже получили несколько хороших ответов, объясняющих, почему не следует), но в некоторых случаях он может оптимизировать разветвления, трубу / пары сокетов, чтение. Вид оптимизаций, которые он может сделать:
trap
не были заданы некоторые s. Например , вsh -c ls
, большинствоsh
реализаций (bash
,mksh
,ksh
,zsh
,yash
, некоторые версииash
) не раскошелиться процессом для запускаls
.ksh93
, подстановка команд не будет создавать канал или ветвь процесса, пока не будет вызвана внешняя команда ($(echo foo)
например, будет расширена доfoo
без трубы / пары сокетов или разветвления).read
встроенная в некоторых оболочках (bash
, AT & Tksh
) не будет делать однобайтный читает , если они обнаруживают STDIN является доступным для поиска (в этом случае они будут делать большие чтения и искать назад до конца , что они предназначены для чтения).источник
ksh93
является ли оболочка ведущей на переднем крае оптимизации, поскольку ее цель / должна рассматриваться как находящаяся на одном уровне с такими языками программирования, какperl
. Так что вы можете посмотретьksh
документацию, код (удачи) и список рассылки для получения дополнительной информации.sh -c 'ps -p "$$"'
что вам даст,ps
а неsh
с этимиsh
реализациями, или с помощью strace / truss / tusc ...ksh -c 'ps; ps'
и bash -c 'ps; ps' интересна. Ksh93 идет дальше в своей оптимизации.ksh
мы говорим здесь.mksh
ведет себя какbash
. Такое поведение в основном предназначено для оптимизации таких вещей, какsystem("some command")
. Обратите внимание, что есть побочный эффект этой оптимизации, когда дело доходит до состояния выхода процессов, завершенных сигналом (в некоторых оболочках).ksh93
имел обыкновение иметь ошибку в том, что он делал оптимизацию, даже когда были установлены ловушки.При взгляде
cat hugeregularfile.txt > /dev/null
на оболочку не позволяют поверить, что действие бесполезно -cat
не является частью оболочки и может вообще что-то делать в теории, а также на практике.Например, пользователь, возможно, переименовал исполняемый файл
rm
вcat
, и внезапно строка выполняет наблюдаемое извне поведение, то есть удаляет файл.Пользователь, возможно, скомпилировал версию,
cat
которая входит в бесконечный цикл, поэтому оболочка не может предположить, что она «известна завершением», как вы предлагаете.Кто-то, возможно, установил версию,
cat
которая работает как задумано, но с дополнительным побочным эффектом установки руткита, если он когда-либо запускается с соответствующими привилегиями - опять же, оболочка должна должным образом выполнить его.источник
mksh
на самом деле оптимизироватьV=$(cat file)
, сделав его встроенным. Таким образом, оболочка может оптимизировать его, но не превратить в простоtouch -a
.cat
это является встроенной вmksh
, но что BUILTIN прибегает к системы ,cat
если он принят какой - либо вариант, поэтому с GNUcat
,mksh -c 'cat /dev/null --help'
не дает такой же результат , какbash -c 'cat /dev/null --help'
, ноmksh -c 'cat --help /dev/null'
это даст вам то же самоеbash -c 'cat --help /dev/null'
(какmksh
кошки встроено разбирает опций POSIX Кстати, в то время как кошка GNU разбирает их по пути GNU).V=$(cat file)
можно оптимизировать с помощьюV=$(< file)
. Это ускоряет работу даже без встроенной функцииcat
.