I have a Bash script that builds a string to run as a command
Script:
#! /bin/bash matchdir="/home/joao/robocup/runner_workdir/matches/testmatch/" teamAComm="`pwd`/a.sh" teamBComm="`pwd`/b.sh" include="`pwd`/server_official.conf" serverbin='/usr/local/bin/rcssserver' cd $matchdir illcommando="$serverbin include='$include' server::team_l_start = '${teamAComm}' server::team_r_start = '${teamBComm}' CSVSaver::save='true' CSVSaver::filename = 'out.csv'" echo "running: $illcommando" # $illcommando > server-output.log 2> server-error.log $illcommando which does not seem to supply the arguments correctly to the $serverbin.
Script output:
running: /usr/local/bin/rcssserver include='/home/joao/robocup/runner_workdir/server_official.conf' server::team_l_start = '/home/joao/robocup/runner_workdir/a.sh' server::team_r_start = '/home/joao/robocup/runner_workdir/b.sh' CSVSaver::save='true' CSVSaver::filename = 'out.csv' rcssserver-14.0.1 Copyright (C) 1995, 1996, 1997, 1998, 1999 Electrotechnical Laboratory. 2000 - 2009 RoboCup Soccer Simulator Maintenance Group. Usage: /usr/local/bin/rcssserver [[-[-]]namespace::option=value] [[-[-]][namespace::]help] [[-[-]]include=file] Options: help display generic help include=file parse the specified configuration file. Configuration files have the same format as the command line options. The configuration file specified will be parsed before all subsequent options. server::help display detailed help for the "server" module player::help display detailed help for the "player" module CSVSaver::help display detailed help for the "CSVSaver" module CSVSaver Options: CSVSaver::save=<on|off|true|false|1|0|> If save is on/true, then the saver will attempt to save the results to the database. Otherwise it will do nothing. current value: false CSVSaver::filename='<STRING>' The file to save the results to. If this file does not exist it will be created. If the file does exist, the results will be appended to the end. current value: 'out.csv' if I just paste the command /usr/local/bin/rcssserver include='/home/joao/robocup/runner_workdir/server_official.conf' server::team_l_start = '/home/joao/robocup/runner_workdir/a.sh' server::team_r_start = '/home/joao/robocup/runner_workdir/b.sh' CSVSaver::save='true' CSVSaver::filename = 'out.csv' (in the output after "runnning: ") it works fine.
8 Answers
You can use eval to execute a string:
eval $illcommando 5your_command_string="..." output=$(eval "$your_command_string") echo "$output" 2I usually place commands in parentheses $(commandStr), if that doesn't help I find bash debug mode great, run the script as bash -x script
don't put your commands in variables, just run it
matchdir="/home/joao/robocup/runner_workdir/matches/testmatch/" PWD=$(pwd) teamAComm="$PWD/a.sh" teamBComm="$PWD/b.sh" include="$PWD/server_official.conf" serverbin='/usr/local/bin/rcssserver' cd $matchdir $serverbin include=$include server::team_l_start = ${teamAComm} server::team_r_start=${teamBComm} CSVSaver::save='true' CSVSaver::filename = 'out.csv' 2./me casts raise_dead()
I was looking for something like this, but I also needed to reuse the same string minus two parameters so I ended up with something like:
my_exe () { mysql -sN -e "select $1 from heat.stack where heat.stack.name=\"$2\";" } This is something I use to monitor openstack heat stack creation. In this case I expect two conditions, an action 'CREATE' and a status 'COMPLETE' on a stack named "Somestack"
To get those variables I can do something like:
ACTION=$(my_exe action Somestack) STATUS=$(my_exe status Somestack) if [[ "$ACTION" == "CREATE" ]] && [[ "$STATUS" == "COMPLETE" ]] ... Here is my gradle build script that executes strings stored in heredocs:
current_directory=$( realpath "." ) GENERATED=${current_directory}/"GENERATED" build_gradle=$( realpath build.gradle ) ## touch because .gitignore ignores this folder: touch $GENERATED COPY_BUILD_FILE=$( cat <<COPY_BUILD_FILE_HEREDOC cp $build_gradle $GENERATED/build.gradle COPY_BUILD_FILE_HEREDOC ) $COPY_BUILD_FILE GRADLE_COMMAND=$( cat <<GRADLE_COMMAND_HEREDOC gradle run --build-file $GENERATED/build.gradle --gradle-user-home $GENERATED --no-daemon GRADLE_COMMAND_HEREDOC ) $GRADLE_COMMAND The lone ")" are kind of ugly. But I have no clue how to fix that asthetic aspect.
To see all commands that are being executed by the script, add the -x flag to your shabang line, and execute the command normally:
#! /bin/bash -x matchdir="/home/joao/robocup/runner_workdir/matches/testmatch/" teamAComm="`pwd`/a.sh" teamBComm="`pwd`/b.sh" include="`pwd`/server_official.conf" serverbin='/usr/local/bin/rcssserver' cd $matchdir $serverbin include="$include" server::team_l_start="${teamAComm}" server::team_r_start="${teamBComm}" CSVSaver::save='true' CSVSaver::filename='out.csv' Then if you sometimes want to ignore the debug output, redirect stderr somewhere.
For me echo XYZ_20200824.zip | grep -Eo '[[:digit:]]{4}[[:digit:]]{2}[[:digit:]]{2}' was working fine but unable to store output of command into variable. I had same issue I tried eval but didn't got output.
Here is answer for my problem: cmd=$(echo XYZ_20200824.zip | grep -Eo '[[:digit:]]{4}[[:digit:]]{2}[[:digit:]]{2}')
echo $cmd
My output is now 20200824