我在这里面临一个小问题,我想将包含空格的字符串传递给另一个程序,以便将整个字符串视为命令行参数。
简而言之,我想通过bash shell脚本执行以下结构的命令: command_name -a arg1 -b arg2 -c“arg with whitespaces here”
但无论我如何尝试,空格都不会保留在字符串中,默认情况下会被标记化。请解决方案,
编辑:这是我脚本的主要部分:
#!/bin/bash
#-------- BLACKRAY CONFIG ---------------#
# Make sure the current user is in the sudoers list
# Running all instances with sudo
BLACKRAY_BIN_PATH='/opt/blackray/bin'
BLACKRAY_LOADER_DEF_PATH='/home/crozzfire'
BLACKRAY_LOADER_DEF_NAME='load.xml'
BLACKRAY_CSV_PATH='/home/crozzfire'
BLACKRAY_END_POINT='default -p 8890'
OUT_FILE='/tmp/out.log'
echo "The current binary path is $BLACKRAY_BIN_PATH"
# Starting the blackray 0.9.0 server
sudo "$BLACKRAY_BIN_PATH/blackray_start"
# Starting the blackray loader utility
BLACKRAY_INDEX_CMD="$BLACKRAY_BIN_PATH/blackray_loader -c $BLACKRAY_LOADER_DEF_PATH/$BLACKRAY_LOADER_DEF_NAME -d $BLACKRAY_CSV_PATH -e "\"$BLACKRAY_END_POINT\"""
sudo time $BLACKRAY_INDEX_CMD -a $OUT_FILE
#--------- END BLACKRAY CONFIG ---------#
答案 0 :(得分:5)
您遇到此问题是因为您将命令存储在变量中,然后再将其展开;除非有充分理由这样做,否则不:
sudo time $BLACKRAY_BIN_PATH/blackray_loader -c $BLACKRAY_LOADER_DEF_PATH/$BLACKRAY_LOADER_DEF_NAME -d $BLACKRAY_CSV_PATH -e "$BLACKRAY_END_POINT" -a $OUT_FILE
如果你真的需要存储命令并在以后使用它,有几个选项; bash-hackers.org wiki有一个good page on the subject。在我看来,最有用的是将命令放在数组而不是简单的变量中:
BLACKRAY_INDEX_CMD=($BLACKRAY_BIN_PATH/blackray_loader -c $BLACKRAY_LOADER_DEF_PATH/$BLACKRAY_LOADER_DEF_NAME -d $BLACKRAY_CSV_PATH -e "$BLACKRAY_END_POINT")
sudo time "${BLACKRAY_INDEX_CMD[@]}" -a $OUT_FILE
这避免了空格分隔单词和单词空间之间的整体混淆,因为单词不是用空格分隔的 - 它们位于数组的单独元素中。使用[@]
后缀以双引号扩展数组会保留该结构。
(BTW,另一种选择是使用转义引号,而不是像你正在做的那样,然后用eval
运行命令。不要这样做;这是引入奇怪的解析错误的好方法。)< / p>
答案 1 :(得分:2)
我有一个建议:
# iterate through the passed arguments, save them to new properly quoted ARGS string
while [ -n "$1" ]; do
ARGS="$ARGS '$1'"
shift
done
# invoke the command with properly quoted arguments
my_command $ARGS
答案 2 :(得分:1)
可能你需要用双引号括起参数(例如“$ {6}”)。
OP评论之后应该是“$ BLACKRAY_END_POINT”
答案 3 :(得分:1)
修改强>:
尝试:
BLACKRAY_END_POINT="'default -p 8890'"
或
BLACKRAY_END_POINT='"default -p 8890"'
或
BLACKRAY_END_POINT="default\ -p\ 8890"
或
BLACKRAY_END_POINT='default\ -p\ 8890'
和
BLACKRAY_INDEX_CMD="$BLACKRAY_BIN_PATH/blackray_loader -c $BLACKRAY_LOADER_DEF_PATH/$BLACKRAY_LOADER_DEF_NAME -d $BLACKRAY_CSV_PATH -e $BLACKRAY_END_POINT"
原始回答:
blackray_loader是shell脚本吗?
以下是在指定参数和处理参数时必须处理此问题的演示:
名为“test.txt”的文本文件(包括行号):
1 two words
2 two words
3 two
4 words
一个名为“spacetest”的脚本:
#!/bin/bash
echo "No quotes in script"
echo $1
grep $1 test.txt
echo
echo "With quotes in script"
echo "$1"
grep "$1" test.txt
echo
使用./spacetest "two--------words"
运行它(用空格替换连字符):
No quotes in script
two words
grep: words: No such file or directory
test.txt:1 two words
test.txt:2 two words
test.txt:3 two
With quotes in script
two words
2 two words
您可以看到,在“无引号”部分,它尝试执行grep two words test.txt
除了“test.txt”之外还将“单词”解释为文件名。此外,echo
删除了额外的空格。
当引用参数时,如第二部分所述,grep
将其视为一个参数(包括额外的空格)并正确处理。 echo
保留了额外的空格。
顺便说一下,我使用额外的空间来帮助演示。
答案 4 :(得分:0)
以下是我通过 exec su USER 或 exec su - USER 重新启动脚本的示例。它适用于:
#
# This script should always be run-as a specific user
#
user=jimbob
if [ $(whoami) != "$user" ]; then
exec su -c "'$(readlink -f "$0")' $(printf " %q" "$@")" - $user
exit $?
fi
答案 5 :(得分:-1)
其他博客上的帖子为我解决了这个空白问题:http://logbuffer.wordpress.com/2010/09/23/bash-scripting-preserve-whitespaces-in-variables/
默认情况下,空格是:
bash> VAR1="abc def gh ijk"
bash> echo $VAR1
abc def gh ijk
bash>
&#34;此行为的原因是内部shell变量 $ IFS(内部字段分隔符),默认为空格,制表符和换行符。 要保留所有连续的空格,您必须将IFS设置为不同的&#34;
IFS 绕过:
bash> IFS='%'
bash> echo $VAR1
abc def gh ijk
bash>unset IFS
bash>
对我的命令案例非常有效:
su - user1 -c 'test -r "'${filepath}'"; ....'
希望这有帮助。