bash:読み取り専用ルートパーティションでread <<<“ $ VARIABLE”を使用する際の問題。既知の回避策はありますか?


11

偶然にも、ATA-ID-to-device-nameスクリプトを使用する必要がありました(/server/244944/linux-ata-errors-translating-to-a-device-name/にあります) 426561#426561読み取り専用 /パーティション。気になる方のために言うと、これはUbuntuの回復コンソールで、/パーティションにアクセスできますが、デフォルトでは読み取り専用でマウントされます。それがなければ、スクリプトが特定の行のためにR / Oシステムで奇妙な動作をすることをおそらく私が知ることはなかったでしょう。

IFS=: read HostMain HostMid HostSub <<< "$HostFull"

これは、書き込み権限がない場合は機能しませ。しかし、失敗するとは思いませんでした。しかし、どうやら<<<オペレーターどこかに一時ファイルを書き込む必要あります。

しかし、一時ファイルの作成を回避する方法はありますか、または、ファイルが書き込まれる場所を指定する方法はありますか?Ubuntuの回復コンソールには、/runディレクトリに書き込み権限がありreadます。これは、一時ファイルを通常とは別の場所に「伝える」ことができた場合にそうなります。


2
@gniourf_gniourfいいえ、「ファイル記述子を開く」ことは問題にならず(なぜそうなのか)、これと/dev/fdは何の関係もありません。<<<ただし、これは一時ファイル(どこかに書き込む必要がある)を作成するため、原因です。
Gilles「SO-悪をやめる」

回答:


8

配列は、一時ファイルを必要とせずに文字列を解析できます。グロビングをオフにすることを忘れないでください。

set -f
IFS=: Hosts=($HostFull)
HostMain=${Hosts[0]}
HostMid=${Hosts[1]}
HostSub=${Hosts[2]}
set +f

2
またはがなくてもIFS、スペースが含ま$HostFullれていないことが確実な場合は、次のようになりますHosts=( ${HostFull//:/ } )。またはスペースがある場合でも:(HostMain=${HostFull%%:*}; HostMid=${HostFull#*:}; HostSub=${HostMid#*:}; HostMid=${HostMid%:*}または同様の何か、私は混乱しています:D)。
gniourf_gniourf 2013年

あなたはパラメータ展開がトリッキータマンであることを示してあなたは、正しいです...
XAE

4

@gniourf_gniourfに同意します。おそらく書き込みアクセス権が必要ですが、ファイル記述子、おそらくファイルへのアクセス権は必要ありません。

これをテストするには、読み取り専用パーティションでコマンドの実行をトレースします。

{ strace -p "$$" & sleep 1; read var1 <<< "hi"; sleep 1; kill "$1"; }

上記はstraceBashシェル(プロセス$$)で実行されます。その後、1秒間スリープし、次にストリングreadから実行します。弦"hi"をこの位置に配置しました。Iその後、sleep複数の第二の1、その後のために。killstrace

この出力を解析すると、ファイルがとして開かれO_WRONLYていることがわかります。これは、ファイルへの書き込み用です。

open("/tmp/sh-thd-4137571604", O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600) = 3

上記では、コマンドシーケンスによって書き込まれているファイルを確認できます。


1
「ファイル記述子を作成する」ためではありません(意味がありません)。ファイルを作成するには。read書き込み用にファイルを開くのは(それはばかげているでしょう)ではありません<<<
Gilles「SO-悪をやめる」

@ギレス-ありがとう、私はそれが私に言っていることを完全に理解していませんでした。Aをクリーンアップ
slm

どうもありがとうございました!非常に優れた手法であり、将来的に同様の問題を抱えて何度も役立つかもしれません。しかし、私心配していること 1つあります。それ/tmpハードコーディングされたパスであるという事実です。そして、おそらくあなたは、それを推測しまし/tmp ISすでに存在しますが、読み取り専用にも!そして、その回復コンソールで作業すると、自分のライブファイルシステムにログインするので、シンボリックリンクなどで混乱させたくありません(そのコンソール内であっても)。
syntaxerror

3

この種のタスクには位置パラメータが非常に便利です。通常、すべてのシェルにも移植可能であり、フォークや一時ファイルの費用はかかりません。

$ HostFull=main:mid:sub    
$ oldIFS=$IFS; IFS=:; set -- $HostFull; IFS=$oldIFS
$ echo $1
main
$ echo $2
mid
$ echo $3
sub

良いアプローチです!ありがとうございました。さらに、外部ツールを必要としないことも気に入っています(通常、これらの制限された環境では通常、このようなツールを見つけることは期待されていません)。唯一の事があり、いくつかの問題を引き起こすがある$1$2$3もの:スクリプトで、これは通常、スクリプトに渡された引数に立つことを覚えておいてくださいそのもの。-そして、その間:IFSがスペースであることを意図している場合、* IFS = *はこの構文では機能しません。IFS = ''を明示的に指定する必要があります。
syntaxerror
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.