我的方案如下:
我有一个shell脚本,该脚本执行一个调用C程序的命令:
name=$1
StringWithSpaces=$name
command="someprogram.out $StringWithSpaces $otherarguments"
$command
其中name是一个带有空格s.a的字符串。 "String With Spaces"
从另一个python脚本传递到外壳。
我的问题是,当我在C语言中读取该参数时,它作为多个参数而不是一个参数传递。我已经尝试过$@
,$*
和所有其他东西。我也尝试过用C编写一个将argv[i]
中的几个StringWithSpaces
分开的函数,但是我有点卡住了。我希望我可以将C中的变量作为一个参数读取,以使程序尽可能简单。
这是确切的shell代码(bash):
#!/bin/bash
#$1 Nombre de la base de datos
#$2 $3 gps coordinates
#$4 geoDistance (radio en km)
#$5 imDownload (a 0: solo se descargan GPS, a 1 también imágenes y tags)
#$Disabled keywords (opcional, lista de keywords separados por comas)
#Generamos el base path
BASE_DIR=`pwd`
#BASE_DIR=${BASE_DIR%/*}
EXE_DIR=$BASE_DIR/FlickrAPI/bin
DB_PATH=$BASE_DIR/data
#Exportamos las librerías, necesario para que funcione el código
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${BASE_DIR}/FlickrAPI/lib
cont=1;
#General DB
name=$1
gps="$2 $3"
geoDistance=$4
numImagesDB=3751
ncores=400;
imDownload=$5
dbDir=$DB_PATH/$name
mkdir "$dbDir";
rm -rf "$dbDir"/imagesDB
rm -rf "$dbDir"/tagsDB
rm -rf "$dbDir"/gps.txt
mkdir "$dbDir"/imagesDB
mkdir "$dbDir"/tagsDB
#tidx=`seq 7 $#`;
#keywords="";
#for ((i=7;i<=$#;i++))
#do
# keywords=$keywords" "${!i};
#done
keywords=$6;
export LD_LIBRARY_PATH=/home/user/anaconda2/lib/
command="$EXE_DIR/get_GPS_bimestral $dbDir $gps z $numImagesDB $ncores $geoDistance $imDownload $keywords"
echo $command
$command
答案 0 :(得分:0)
我的问题是,当我在C语言中读取该参数时,它将作为多个参数而不是仅作为一个参数传递。
在脚本中替换
command="$EXE_DIR/get_GPS_bimestral $dbDir $gps z $numImagesDB $ncores $geoDistance $imDownload $keywords" echo $command $command
作者
command="$EXE_DIR/get_GPS_bimestral \"$dbDir $gps z $numImagesDB $ncores $geoDistance $imDownload $keywords\""
echo $command
echo $command | bash
说明:
如果shell脚本 b 是:
./a.out "$* 3 4"
和 c.c 是
#include <stdio.h>
int main(int argc, char ** argv)
{
printf("argc = %d, argv[1] = '%s'\n", argc, argv[1]);
}
然后:
pi@raspberrypi:/tmp $ ./b 1 2
argc = 2, argv[1] = '1 2 3 4'
C程序只接收一个arg,没关系
但是如果将脚本修改为例如:
command="./a.out \"$* 3 4\""
echo $command
$command
不起作用:
pi@raspberrypi:/tmp $ ./b 1 2
./a.out "1 2 3 4"
argc = 5, argv[1] = '"1'
因此,如果您想存储在var中以回显然后执行它,则可以执行以下操作:
command="./a.out \"$* 3 4\""
echo $command
echo $command | bash
执行:
pi@raspberrypi:/tmp $ ./b 1 2
./a.out "1 2 3 4"
argc = 2, argv[1] = '1 2 3 4'
当然,如果您希望将例如4作为单独的参数接收,只需将其放在字符串之外:
command="./a.out \"$* 3\" 4"
echo $command
echo $command | bash
执行:
pi@raspberrypi:/tmp $ ./b 1 2
./a.out "1 2 3" 4
argc = 3, argv[1] = '1 2 3'
答案 1 :(得分:0)
使用以下命令将命令放入数组中
Command=(someprogram.out "$StringWithSpaces" "$otherarguments")
如@
所示,使用"${Command[@]}"
来扩展数组的引号来请求其所有成员时,bash会将其数组成员扩展为单个单词。因此,带有空格的所需字符串将保留为单个字符串。
这是一个示例脚本:
#!/bin/bash -e
function ShowArguments()
{
for argument in "$@"; do
echo "Argument: $argument"
done
}
Argument1="abc def"
Argument2="pdq xyz"
Command=(ShowArguments "$Argument1" "$Argument2")
echo "${Command[@]}"
"${Command[@]}"
上面的输出是:
ShowArguments abc def pdq xyz Argument: abc def Argument: pdq xyz
您可能希望"$otherarguments"
为$otherarguments
。或者,如果它包含一个带有空格的字符串,应将其保留为字符串,则应使用用引号${otherarguments[@]}
进行扩展的数组来处理它。这是一个引用用于保留参数的变量之一的示例:
#!/bin/bash -e
function ShowArguments()
{
for argument in "$@"; do
echo "Argument: $argument"
done
}
Argument1="Single argument with multiple words"
Argument2=("Multiple argument" with various "numbers of words")
Command=(ShowArguments "$Argument1" "${Argument2[@]}")
echo "${Command[@]}"
"${Command[@]}"
它产生:
ShowArguments Single argument with multiple words Multiple argument with various numbers of words Argument: Single argument with multiple words Argument: Multiple argument Argument: with Argument: various Argument: numbers of words
在那之后,您可能想用引人注目的自变量的更高级命令替换echo
,以向用户显示正确的引号。但这是一种美观或用户界面选择;不会影响执行的命令。