Это ожидаемое поведение.
Любой из них предотвратит обновление atime, но они независимы.
В ядре нет системного вызова для запроса общего состояния. Вы должны проверить оба из них самостоятельно.
Это связано с тем, как/dev/stdin
(на самом деле/proc/self/fd/0
)реализовано в Linux (и Cygwin, но не в других системах ).
В Linux открытие /dev/stdin
не похоже на выполнение dup(0)
, он просто заново открывает тот же файл, что и при открытии на fd 0. Он не использует описание открытого файла , на которое ссылается fd 0 (с режимом только для чтения ), но получает совершенно не связанное новое описание открытого файла с режимом как указано в open()
.
Таким образом, если sops -d /dev/stdin
открывается /dev/stdin
в режиме чтения+записи, а fd 0 был открыт в режиме чтения -только в /some/file
, /some/file
будет открыт в режиме чтения+записи.
По сути, cmd /dev/stdin < file
есть то же самое, что и cmd file < file
. Вы обнаружите, что /dev/stdin
— это просто символическая ссылка¹ наfile
:
/tmp$ namei -l /dev/stdin < file
f: /dev/stdin
drwxr-xr-x root root /
drwxr-xr-x root root dev
lrwxrwxrwx root root stdin -> /proc/self/fd/0
drwxr-xr-x root root /
dr-xr-xr-x root root proc
lrwxrwxrwx root root self -> 73569
dr-xr-xr-x stephane stephane 73569
dr-x------ stephane stephane fd
lr-x------ stephane stephane 0 -> /tmp/file
drwxr-xr-x root root /
drwxrwxrwt root root tmp
-rw-r--r-- stephane stephane file
Может стать хуже. Если бы он открывался с O _TRUNCATE, файл был бы усечен. Если бы fd 0 указывал на конец канала для чтения, а /dev/stdin
был открыт в режиме только для записи -, вы бы получили другой конец канала.
Но используя:
cat file | cmd /dev/stdin
Защитит от cmd
перезаписи file
, так как все cmd
увидит канал.И даже если бы он открылся только в режиме записи -, он не смог бы вернуться к file
, он просто добрался бы до конца записи канала, а единственным файловым дескриптором на конце чтения был бы cmd
. ] стандартный ввод.
Другие операционные системы не имеют проблемы, так как открытие /dev/stdin
похоже на выполнение dup(0)
, поэтому вы получаете то же описание открытого файла , и если вы открываете в несовместимом режиме, open()
системный вызов просто терпит неудачу.
¹ технически, как отметил @user414777 в комментариях, /proc/<pid>/fd/<fd>
являются волшебными символическими ссылками в том смысле, что они, например, могут достигать мест, недоступных обычным символическим ссылкам, но когда дело доходит до их открытия, прошлое на этапе разрешения пути они действуют как обычные символические ссылки в том смысле, что вы просто открываете целевой файл