リダイレクトのエラーの謎2

Sun Sep 24 20:38:36 JST 2023 (modified: Sun Sep 24 20:41:05 JST 2023)
views: 517, keywords:シェル芸, 自作シェル, bash この記事は最終更新日が1年以上前のものです。

 このときのリダイレクトに関する調査の続きです。

n>&mnが大きいときにmが怒られるパターン

 上記のリンク先の記事では触れてませんが、 もう一つ、Bashにはこういう変な挙動があります。

$ ulimit -n
   1024                              #開けるファイル記述子の上限は1024
   $ ls /var 1000>&2 #これは大丈夫
   backups  cache  crash  lib  local  lock  log  mail  metrics  opt  run  snap  spool  tmp
   $ ls 1024>&2
   bash: 2: 不正なファイル記述子です #なぜか1024ではなく2のほうが叱られる
   $ ls 100000000000000000000>&2
   ls: '100000000000000000000' にアクセスできません:(略) #数字が大きいとちゃんと叱られる

$ ls 1024>&2では1024のほうを叱って欲しいのに、なぜか2のほうが叱られます。

 で、これなんでだろうと思ってBashのコードを読んでみましたが、 わけわかめで玉砕しました。しかしこのたび、 自分で処理を書いてみたらなんとなく分かりました。 Rustで書くとこんな感じ。

/* m>&n の処理 */
   31 match unistd::dup2(n, m) {
   32     Ok(_) => true,
   33     Err(Errno::EBADF) => {
   34         eprintln!("sush: {}: Bad file descriptor", n);
   35         false
   36     },
   37     Err(_) => {
   38         eprintln!("sush: dup2 Unknown error");
   39         false
   40     },
   41 }

dup2はerrnoEBADFしか残さないので、 31行目のmnのどっちがダメなファイル記述子なのか分かりません。 なので、34行目でnのほうを断罪するしかないという実装になりました。 dup2を実行する前になにか変だと分かればこれは防げます。 ls 100000000000000000000>&2 の場合は文字列100000....を数字にするときにエラーになるので、 さっきのBashの例では10000....のほうが叱られるのだと思われます。

まだわからんこと

 前回のこれのやりなおしですが、これがまだ分かりません。情報求む。

$ echo 1>&1000
   bash: 1000: 不正なファイル記述子です #開いてないので1000が怒られる
   $ echo 2>&1000
   bash: 1000: 不正なファイル記述子です #同上
   $ echo 3>&1000
   bash: 1000: 不正なファイル記述子です #同上
   $ echo 1>&1000000000000
   bash: 1000000000000: 不正なファイル記述子です #同上
   $ echo 2>&1000000000000
   bash: 2: 不正なファイル記述子です #???????????????????????
   $ echo 3>&1000000000000
   bash: 3: 不正なファイル記述子です #これは3が開いてないので分かる
ノート   このエントリーをはてなブックマークに追加 
 

prev:日記(2023年9月23日) next:日記(2023年9月28日)

やり散らかし一覧

記事いろいろ