I didn't think this would be as tricky as it turned out to be, but here I am. I'm trying to write a Nautilus script in Python to upload one or more images to Imgur just by selecting and right clicking them. It works well enough with both single images and multiple images - as long as they don't contain any whitespace. In fact, you can upload a single image containing whitespace, just not multiple ones.
The problem is that NAUTILUS_SCRIPT_SELECTED_FILE_PATHS returns all the selected files and directories as a space separated string. So for example, it could look like this:
print os.environment['NAUTILUS_SCRIPT_SELECTED_FILE_PATHS']
/home/nevon/Desktop/test image.png /home/nevon/Desktop/test.jpg
What I need is a way to -either in bash or Python- escape the spaces in the path - but not the spaces that delimit different items. Either that, or a way to put quotation marks around each item.
The ultimate solution would be if I could do 开发者_如何学Gothat in bash and then send the items as separate arguments to my python script. Something like:
python uploader.py /home/nevon/Desktop/test\ image.png /home/nevon/Desktop/test.jpg
I've tried RTFM'ing, but there doesn't seem to be a lot of good solutions for this. At least not that I've found. Any ideas?
I think that $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
should be newline delimited, not space delimited. In that case, the following should work from bash:
echo -e $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS | xargs python uploader.py
Skipping one level of evaluation shows that the nautilus documentation is incomplete and that there is a better way much less subject to who-knows-how-many levels of interpretation. Nautilus passes selected files as script arguments:
$ cat ~/.gnome2/nautilus-scripts/arguments.sh
#!/bin/sh
rm -f /tmp/arguments.*
outf=/tmp/arguments.$$
echo "$0: $#" > $outf
while [ $# -gt 0 ] ; do
echo "$1"
if [ ! -r $1 ] ; then echo "cwd is not correct"; fi
shift
done >> $outf
echo paths $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS >> $outf
for i in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS ; do
echo "+$i+"
done >> $outf
I sent the output to /tmp
since I didn't want to hunt for the stdout. Given:
$ ls -1
a
b
c with space
d
e with space
g
Select all the files in the directory and Scripts->arguments.sh yields:
$ cat /tmp/arguments.20447
/home/msw/.gnome2/nautilus-scripts/arguments.sh: 6
a
b
c with space
d
e with space
g
paths /home/msw/junk/a /home/msw/junk/b /home/msw/junk/c with space
/home/msw/junk/d /home/msw/junk/e with space
/home/msw/junk/g
+/home/msw/junk/a+
+/home/msw/junk/b+
+/home/msw/junk/c+
+with+
+space+
+/home/msw/junk/d+
+/home/msw/junk/e+
+with+
+space+
+/home/msw/junk/g+
Could I have quoted $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
to avoid this? Sure. I didn't to demonstrate that how many levels of interpolation with the variable is questionable, but argv
stays unmolested.
Use argv (or sys.argv
in Python) and save some headache. Also the documented semantics of the environment variables is weird.
I can't test this as I'm at a Windows machine, but have you tried using $NAUTILUS_SCRIPT_SELECTED_FILE_URIS instead? Then, in python you could get the paths with something like:
[f.strip() for f in os.environment['NAUTILUS_SCRIPT_SELECTED_FILE_URIS'].split('file://') if len(f) > 0]
It turns out, echo
sometimes turns newlines in variables into spaces. The following should work:
echo -e "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | xargs python uploader.py
精彩评论