Run a string as a command within a Bash script

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.

2

8 Answers

You can use eval to execute a string:

eval $illcommando 
5
your_command_string="..." output=$(eval "$your_command_string") echo "$output" 
2

I usually place commands in parentheses $(commandStr), if that doesn't help I find bash debug mode great, run the script as bash -x script

3

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

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like