В каталоге /etc/skel
находится шаблон домашнего каталога. Вы можете попробовать восстановить права доступа к основным папкам в соответствии с папками в /etc/skel.
В будущем используйте rsync/cp/scp с -переключателем p для сохранения разрешений.
Обычно оболочки UNIX просто открывают необходимые файлы с помощью open
, затем fork
сами, затем dup2
ранее полученные fd в stdin/stdout/stderr (0/1/2 ), чтобы они Обрабатываются соответственно программой они execve
позже. Для повышения производительности со встроенными командами может быть по-другому (, так как fork
и execve
довольно дороги ), но семантика та же.
Если вы имеете в виду правила синтаксического анализа командной строки, то они описаны в POSIX. Они не различают встроенные и внешние программы.
Перенаправление дескриптора файла d0 в файл или из файла включает следующие шаги:
F_DUPFD
системного вызова fcntl
. Если d0 не открыто, ничего не делайте на этом шаге. F_DUPFD
или с помощью dup2
. Причина, по которой необходимо дублирование в случайном порядке, заключается в том, что приложения не могут выбирать файловый дескриптор при открытии файла. Шаги 2–4 можно пропустить, если d1 = d0 , но оболочка не может этого гарантировать.
Когда перенаправление применяется к внешней команде, оно выполняется в дочернем процессе после того, как дочерний процесс был создан с помощью fork
, но до выполнения внешней команды с помощью execve
. Когда перенаправление применяется к внутренней команде оболочки (, например. вызов функции, цикл и т. д. ), эти шаги должны выполняться в исходном процессе¹, и оболочке необходимо восстановить исходное состояние файлового дескриптора после завершения перенаправленной команды путем дублирования d2 вернуться к d0 и закрыть d2(или просто закрыть d0 , если он изначально не был открыт ).
Канал включает в себя аналогичные шаги, но немного сложнее, потому что создание канала создает два файловых дескриптора (конец чтения и конец записи )и есть два подпроцесса.
Создайте трубу с помощьюpipe
. Системный вызов pipe
возвращает пару файловых дескрипторов {r , w }.
В левой -стороне трубы:
В правой -стороне трубы:
В оболочках, которые выполняют обе стороны канала в подпроцессах, родительский процесс закрывает r и w , затем ожидает завершения двух сторон канала.
В оболочках, которые выполняют правую -сторону канала в родительском процессе, оболочка ожидает завершения левой -стороны, затем закрывает 0 и восстанавливает исходный дескриптор файла в 0.
Вы можете посмотреть, что делают оболочки, прочитав их исходный код или проследив за их работой с помощью отладчика. Например, в Linux посмотрите системные вызовы в действии с помощью
strace sh -c '…'
¹ Древние оболочки (до POSIX )выполняли перенаправленные сложные команды в подпроцессе, поэтому они не требовали восстановления перенаправления.