我正在研究树莓派(Raspberry Pi OS):
我运行一个 Bash#!/bin/bash
脚本,需要在名称中包含空格的目录下保存一个文件(拍摄的图片)。
就我而言,目录是:/media/pi/test 1 2 3
我运行的命令并执行我想要的操作:
raspistill -awb greyworld -vf -hf -o /media/pi/"test 1 2 3"/test.jpg
拍张照片并将其保存在那里,效果很好。
我的问题是,我希望“test 1 2 3”位于变量内,如下所示:
usbToSave="\"test 1 2 3\"" #usbToSave is now "test 1 2 3"
raspistill -awb greyworld -vf -hf -o /media/pi/$usbToSave/test.jpg
但上面的内容会给我这个错误:
Invalid command line option (1)
我不明白为什么。我确信类似的问题已经在论坛的某个地方得到了回答,但我找不到它。我想我没有使用正确的关键字来搜索它。
笔记:
如果我的目录没有空格,例如/media/pi/test
Bash 脚本:
usbToSave="test"
raspistill -awb greyworld -vf -hf -o /media/pi/$usbToSave/test.jpg
工作没有错误。
答案1
usbToSave="\"test 1 2 3\""
raspistill -awb greyworld -vf -hf -o /media/pi/$usbToSave/test.jpg
在这里,您将引号放入变量的值中,赋值后,它将包含"test 1 2 3"
.然后,您在不使用双引号的情况下扩展变量,从而遇到了分词的问题(请参阅下面的链接)。结果是raspistill
获取/media/pi/"test
、1
、2
和3"/test.jpg
作为不同的命令行参数。
请注意,您放入变量中的引号在结果单词( 的参数)中是原义的raspistill
。变量展开式为不是纯文本替换或宏扩展:一般来说,来自变量的任何内容都不被视为 shell 语法。除了引号之外,shell 运算符(如&&
、>
、等|
);
在从变量扩展时也只是常规字符。单词分割和文件名生成是这里唯一的例外。
你需要做的是:
usbToSave="test 1 2 3"
raspistill -awb greyworld -vf -hf -o "/media/pi/$usbToSave/test.jpg"
也就是说,在双引号内进行变量扩展,这可以防止分词(和文件名生成)。
看:
答案2
了解变量和引用在 shell 中的工作原理。阅读扩展在man bash
。
usbToSave="test 1 2 3"
raspistill -awb greyworld -vf -hf -o /media/pi/"$usbToSave"/test.jpg
shell 中的变量不是您从编程语言中了解的真正变量。它们在某种程度上类似于扩展到值的宏。如果不引用变量,分词结果会发生这种情况,双引号可以防止这种情况发生。
答案3
或者,您也可以逃脱定义变量时的空格:相当于usbToSave="test 1 2 3"
前面答案中的字符所在usbToSave=test\ 1\ 2\ 3
的位置\
逃脱以下空格(或您可能想要在字符串中使用的其他特殊字符,例如$
)
编辑:我在转义字符串周围添加了双引号和引号,明确了它们的执行方式:
$ usbToSave_A="test 1 2 3"
$ usbToSave_B=test\ 1\ 2\ 3
$ echo $usbToSave_A
test 1 2 3
$ echo $usbToSave_B
test 1 2 3
$ echo /media/pi/"$usbToSave_A"/test.jpg
/media/pi/test 1 2 3/test.jpg
$ echo /media/pi/"$usbToSave_B"/test.jpg
/media/pi/test 1 2 3/test.jpg
$ echo "/media/pi/$usbToSave_A/test.jpg"
/media/pi/test 1 2 3/test.jpg
$ echo "/media/pi/$usbToSave_B/test.jpg"
/media/pi/test 1 2 3/test.jpg
$ usbToSave_C='"test 1 2 3"'
$ usbToSave_D="test\ 1\ 2\ 3"
$ echo $usbToSave_C
"test 1 2 3"
$ echo $usbToSave_D
test\ 1\ 2\ 3
$ echo "/media/pi/$usbToSave_C/test.jpg"
/media/pi/"test 1 2 3"/test.jpg
$ echo "/media/pi/$usbToSave_D/test.jpg"
/media/pi/test\ 1\ 2\ 3/test.jpg
$ echo "/media/pi/"$usbToSave_C"/test.jpg"
/media/pi/'test 1 2 3'/test.jpg
$ echo "/media/pi/"$usbToSave_D"/test.jpg"
/media/pi/test\ 1\ 2\ 3/test.jpg