terminal
su
、w3m
との交差点で発生する非常に奇妙な問題があります/dev/null
。
からsu -
に移動すると、次のコマンドは機能しません。user1
user2
$ w3m zz.html 2>/dev/null
Error occurred while reset 800b: errno=25
しかし、同じコマンドは2>/dev/null
リダイレクトなしでうまく機能します。
$ w3m zz.html
user2
最後に(から切り替えるのではなく)直接ログインすると、user1
すべてがうまくいきます(存在するか2>/dev/null
どうか)。
w3m
以下をstrace
実行すると、strace -o zz.strace w3m zz.html 2>/dev/null
この時点で2つのケース(動作と非動作)が分裂し始めることがわかります。
ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=77, ws_col=199, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(2, TIOCGWINSZ, 0x7318fb8e7c40) = -1 ENOTTY (Inappropriate ioctl for device)
fstat(2, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x3), ...}) = 0
ioctl(2, TCGETS, 0x7318fb8e7400) = -1 ENOTTY (Inappropriate ioctl for device)
brk(0x16a51a8a1000) = 0x16a51a8a1000
brk(0x16a51a8b1000) = 0x16a51a8b1000
brk(0x16a51a8c2000) = 0x16a51a8c2000
brk(0x16a51a8d2000) = 0x16a51a8d2000
brk(0x16a51a8e8000) = 0x16a51a8e8000
ioctl(2, TCGETS, 0x7318fb8e7bd0) = -1 ENOTTY (Inappropriate ioctl for device)
ioctl(2, TCGETS, 0x7318fb8e7bc0) = -1 ENOTTY (Inappropriate ioctl for device)
ioctl(2, SNDCTL_TMR_START or TCSETS, {B0 -opost -isig -icanon -echo ...}) = -1 ENOTTY (Inappropriate ioctl for device)
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x7), ...}) = 0
write(1, "Error occurred while reset 800b:"..., 42) = 42
write(2, "\33[?1049h\33[22;0;0t\33[H\33[2J\33[39;49m"..., 58) = 58
ioctl(2, TCGETS, 0x7318fb8e7ba0) = -1 ENOTTY (Inappropriate ioctl for device)
ioctl(2, SNDCTL_TMR_START or TCSETS, {B0 -opost -isig -icanon -echo ...}) = -1 ENOTTY (Inappropriate ioctl for device)
exit_group(1) = ?
+++ exited with 1 +++
私が知る限り、これはTIOCGWINSZ
ioctl
端末のサイズに関連しているようです。ただし、この問題の原因が正確に何であるかが見つかりません。
答え1
コメントのため更新されました。
-
明らかに、Debianはこのようなナンセンスを修正しました。問題の核心は同じようにハイブリッド環境です。
問題は/proc/*/fd/*
!
の素晴らしい答えを引用してユーザー 1686、いいねを押すのを忘れないでくださいsudo以降、/dev/stderrに対する権限が拒否されました。。
問題の核心は次のとおりです。
これはLinux実装の/ procに関するよく知られた問題で、長年にわたって解決されていません。 Linuxの場合は/ proc /の下のリンクを開きます。/fd/ファイル記述子はdup()のように直接コピーされません(理論的には/ procリンクはこれを達成できますが)。代わりにファイルを再度開き、新しい権限確認が行われます。
この質問の元の投稿はTheodore Tso(2008!)から来ました。Re: RFC: /dev/stdin、シンボリックリンクと権限
解決策
pty
新しいものを得る時間ですユーザーB:
userA:~$ su -l -P userB
~から男性ページsu
:
-, -l, --login Start the shell as a login shell with an environment similar to a real login: • clears all the environment variables except TERM and variables specified by --whitelist-environment • initializes the environment variables HOME, SHELL, USER, LOGNAME, and PATH • changes to the target user’s home directory -P, --pty Create a pseudo-terminal for the session. The independent terminal provides better security as the user does not share a terminal with the original session. This can be used to avoid TIOCSTI ioctl terminal injection and other security attacks against terminal file descriptors. The entire session can also be moved to the background (e.g., su --pty - username -c application &). If the pseudo-terminal is enabled, then su works as a proxy between the sessions (sync stdin and stdout). This feature is mostly designed for interactive sessions. If the standard input is not a terminal, but for example a pipe (e.g., echo "date" | su --pty), then the ECHO flag
Debian Bookwormでテストする機会がありました。
ghu@magnetron:/tmp$ w3m testing.html 2>/dev/null
Error occurred while reset 800b: errno=25
ughu@magnetron:/tmp$ exit
logout
tukan@magnetron:~/Downloads/html$ su -l -P ughu
Password:
ughu@magnetron:~$ cd /tmp
ughu@magnetron:/tmp$ w3m testing.html 2>/dev/null
ughu@magnetron:/tmp$ exit
OPディスカッションに基づいて編集
OPと私のバージョンの違い(2.33.1-0.1
vs 2.38.1-1.1+b1
- ここからフルバージョン)変更ログ)。
OPstderr
は、su -
例えばシェルnon-existing-command 2>/dev/null
またはnon-existing-command 2>/tmp/output
。
一方、出力が長すぎると(エラーメッセージに示すように〜2 ^ 15(32768)バイトにリセットされる可能性があります。16進数:800bは12月です。32768+0+0+11)アプリケーションと同様に、w3m
リセットは完了し、ユーザー権限を再確認しますが失敗します。
私が知らないいくつかのパッチはutil-linuxのバージョン2.33.1-0.1
と2.38.1-1.1+b1
。
結論として
最新バージョンを使用する必要があります(どのバージョンで動作しているかわかりません)、私の場合、スイッチは正しく2.38.1-1.1+b1
動作しました-P
。これにより、w3m
上記のように大規模な出力に対してもリダイレクトが機能します。