woof 不适用于名称包含空格或括号的文件

woof 不适用于名称包含空格或括号的文件

我编写了一个 bash 脚本并将其放入~/.local/share/nautilus/scripts/

在 nautilus 中,如果我右键单击文件并选择脚本菜单,它将启动 http 服务器来共享当前文件,并显示二维码,因此手机可以扫描网址来下载文件。当您关闭二维码窗口时,服务器将停止。

一切正常,但是当文件名包含空格或括号时,我无法下载文件。

▶ cat ~/.local/share/nautilus/scripts/share-http.bash 
#!/bin/bash

port=8080
pkill woof
file=`echo -n $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS|sed 's/\ *$//'|sed 's/\ /\\\ /g'`
echo $file >> ~/tmp
woof -c 4 -p $port \'$file\' &
# woof -c 4 -p $port $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS &
url=`ifconfig|awk '/inet /&&!/127./{print $2}'|sed 's/.*://'`
qrencode -s 5 -o /tmp/url.png "http://$url:$port"
eog /tmp/url.png && pkill woof

该脚本需要 woof+qrencode 才能运行。

我发现该字符串$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS有一个后缀空格,所以我修改了代码。

在 bash 中,这应该可以工作:

▶ woof -c 4 -p 8080 '/home/eexp/Download/IMG_20161024_132 037.jpg'

但仍然失败。您会看到 ps 中的命令有撇号,即使在空格前有反斜杠。

▶ pgrep woof
13109 /usr/bin/python /usr/bin/woof -c 4 -p 8080 '/home/eexp/Download/IMG_20161024_132 037.jpg'
▶ pgrep woof
13531 /usr/bin/python /usr/bin/woof -c 4 -p 8080 '/home/eexp/Download/IMG_20161024_132\ 037.jpg'

答案1

在 GNU/Linux 中,除/\0(ASCII NUL) 之外的任何字符都可以作为有效的文件名组成字符。因此,空格、制表符,甚至换行符都是有效的文件名组成字符。当您有任何这样的文件名时,您需要使用任何简单的转义机制来获取字符的字面含义。

例如,对于如下文件名:

foo bar spam.txt

您可以使用单引号、双引号或\转义空格:

'foo bar spam.txt'
"foo bar spam.txt"
foo\ bar\ spam.txt

建议使用单引号,因为文件名foo $bar spam.txt如果使用双引号,shell 将把它$bar作为变量扩展,$使用时未转义的情况也是如此\

无需转义,shell 将根据IFS环境变量的值(默认为空格、制表符、换行符)执行单词拆分,并对字符串进行路径名扩展(如果文件名中有*, ?, 的话[])。

如果是变量,则需要用双引号括住变量扩展:

file='foo bar spam.txt'
echo "$file"

Simple$file又会陷入词语拆分(和路径名扩展)的泥潭。

答案2

我解决了这个问题。这个 $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS 有一个后缀“\x0A”,所以我更新了脚本,一切正常。

#!/bin/bash

port=8080
pkill woof
file=`echo -n $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS|sed 's/\x0A//g'`
echo "->$file<-" >> ~/tmp
woof -c 4 -p $port "$file" &
url=`ifconfig|awk '/inet /&&!/127./{print $2}'|sed 's/.*://'`
qrencode -s 5 -o /tmp/url.png "http://$url:$port"
eog /tmp/url.png && pkill woof

相关内容