コマンドを並列に実行したいときxargsは便利です。今回はxargsなしだとコマンドが実行できるのに、xargsの中でコマンド実行するとinappropriate ioctl for device
エラーが出たのでその原因と対処についてメモします。
inappropriate ioctl for deviceエラー
inappropriate ioctl for device
というエラー自体は、ttyを必要とするプログラムでttyがないときに発生します。xargsは標準入力を受けると子プロセスに渡さないので、子プロセスがttyを必要とするとエラーが発生します。
このため、ほかのコマンドでもttyが必要ならこのエラーは発生します。
$ echo "sane" | xargs stty stty: 'standard input': Inappropriate ioctl for device
ttyがない時の対処
xargsで実行したコマンドにttyを渡すには-o
を追加します。-o
は--open-tty
の略で、子プロセスに標準入力をttyとして再オープンするオプションです。
$ xargs --help -o, --open-tty Reopen stdin as /dev/tty in the child process before executing the command; useful to run an interactive application.
つまりこのようにします。
$ echo "sane" | xargs -o stty
tenv 4.0.0-4.1.0でも発生する
次の環境下でtenvでも本エラーが発生します。
- tenv 4.1.0 (aquaやインストール1)
- tenvでインストールしたterraform
- argsの中でterraformを実行すると発生
再現コードです。
$ tenv --version tenv version v4.1.0 $ echo "foo" | xargs -I{} -P 1 -n1 bash -c "terraform --version" Failure during terraform call : fork/exec /home/guitarrapc/.local/share/aquaproj-aqua/bin/tenv: inappropriate ioctl for device
エラーメッセー字からaquaでインストールしたtenvが出していることがわかります。 aqua移行前は生じてなかったのでaquaが原因かと考えていましたが、以下のIssueからtenv 4.0.1-4.1.0にあるバグのようです。
実際、4.2.0-beta2にアップグレードすると本バグは解消します。aqua-proxyの仕組み由来かと疑っていましたが、誤解でした。
$ tenv --version tenv version v4.2.0-beta2 $ echo "foo" | xargs -I{} -P 1 -n1 bash -c "terraform --version" Terraform v1.9.8 on linux_amd64 Your version of Terraform is out of date! The latest version is 1.10.5. You can update by downloading from https://www.terraform.io/downloads.html
なお、4.1.0でもxargsに-o
を追加することで回避できます。
$ echo "foo" | xargs -I{} -o -P 1 -n1 bash -c "terraform --version" Terraform v1.9.8 on linux_amd64 Your version of Terraform is out of date! The latest version is 1.10.5. You can update by downloading from https://www.terraform.io/downloads.html
まとめ
xargsでコマンド実行時inappropriate ioctl for device
エラーが出るのは、ttyが必要な処理を実行しているためです。
このエラーが出るときは、xargsに-o
を追加してttyを再オープンすることで解消できます。
- homebrewでインストールしたtenvでも発生します↩