如何在 bash 中在带空格的目录周围使用双引号

如何在 bash 中在带空格的目录周围使用双引号

我正在研究树莓派(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/testBash 脚本:

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/"test123"/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

相关内容