我编写了一个 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