bash:在只读根分区上使用read <<<“ $ VARIABLE”时出现一些问题。任何已知的解决方法?


11

碰巧的是,我不得不使用我的ATA-ID-to-device-name脚本(在这里找到:https : //serverfault.com/questions/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)'所以

Answers:


8

数组可以进行字符串解析,而无需临时文件。别忘了关闭glob。

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

2
甚至没有IFS,如果您确定其中没有空格$HostFullHosts=( ${HostFull//:/ } )。或即使有空格:(HostMain=${HostFull%%:*}; HostMid=${HostFull#*:}; HostSub=${HostMid#*:}; HostMid=${HostMid%:*}或类似的东西,我也很困惑:D)。
gniourf_gniourf

你是对的,因为你看参数扩展是棘手bussines ...
西航

4

我同意@gniourf_gniourf,您可能需要写访问权限,但不需要文件描述符,很可能是文件。

您可以通过在只读分区中跟踪命令的执行情况来进行测试。

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

上面的代码将strace在Bash shell(进程$$)上运行。然后休眠1秒钟,然后read从这里STRING 运行。我把弦"hi"放在这个位置。然后我sleep一个更秒钟,然后killstrace

解析此输出时,您会注意到一个文件以形式打开O_WRONLY,用于写入文件。

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

在上方,我们可以看到您的命令序列正在写入什么文件。


1
不要“创建文件描述符”(没有任何意义)。创建文件。不是read打开文件进行写入(这很愚蠢),而是<<<
吉尔斯(Gilles)'所以

@吉尔斯-谢谢,我不太明白它在告诉我什么。清理A.
SLM

非常感谢你!一项非常好的技术,将来甚至可能在类似问题上对我有很多帮助。然而,有一件事担心我,这是一个事实,/tmp是一个硬编码路径。大概你已经猜到了,/tmp IS出现了,但只读的!而且由于在该故障恢复控制台上工作将使我登录到实时文件系统,所以我不希望通过符号链接或其他任何方式陷入混乱(即使在该控制台中也是如此)。
语法错误

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 =''
语法错误
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.