Bash - create JSON string dynamically and add as argument [duplicate] - bash

This question already has answers here:
Why does shell ignore quoting characters in arguments passed to it through variables? [duplicate]
(3 answers)
Closed 3 years ago.
I have a shell script with 3 Parameters:
#!/bin/bash
VHOST=$1
EXCHANGE=$2
DELAY=$3
RABBIT_CMD="docker exec rabbit rabbitmqadmin -u rabbit -p rabbit --vhost=$VHOST"
COMPLEX_CMD="$RABBIT_CMD declare queue name=${EXCHANGE}-delay"
COMPLEX_CMD="$COMPLEX_CMD arguments="
COMPLEX_CMD="${COMPLEX_CMD}'{\"x-message-ttl\":$DELAY,\"x-dead-letter-exchange\":\"$EXCHANGE\", \"x-dead-letter-routing-key\":\"worker\"}'"
echo $COMPLEX_CMD
$COMPLEX_CMD
Now I call this script
./script.sh rdb blah 5000
The second last line echo $COMPLEX_CMD outputs the following line:
docker exec rabbit rabbitmqadmin -u rabbit -p rabbit --vhost=rdb declare queue name=blah-delay arguments='{"x-message-ttl":5000,"x-dead-letter-exchange":"blah","x-dead-letter-routing-key":"worker"}'
When I copy-paste this into my bash and execute it, it works without any problems. But when I want to execute this in the script (last line $COMPLEX_CMD), I get the following error:
ERROR: Could not parse JSON:
'{"x-message-ttl":5000,"x-dead-letter-exchange":"blah","x-dead-letter-routing-key":"worker"}'
How do I have to escape my strings within the JSON in the right manner?

Found the solution: Just put eval before the $COMPLEX_CMD, so change the last line to
eval $COMPLEX_CMD

Related

How to write bash commands inside SFTP [duplicate]

This question already has answers here:
Using variables inside a bash heredoc
(3 answers)
Closed last year.
I have the below script to download today's file from the server
#!/bin/sh
IFS='
'
SYS_DT=$(date '+%d%h%Y')
SYS_FILE='BOMExtract_'$SYS_DT'.xlsx'
sshpass -p "123" sftp "admin#XXXX" << 'EOF'
cd /u01/admin/Oracle
lcd /u01/usr
get $SYS_FILE
But it is not taking the value of SYS_FILE in getting command. Can anyone please help to write bash inside sftp commands?
I removed the quotes around EOF and that fixed the issue.Thanks Barmar

Golang - how to spawn a process that takes a glob pattern as one of its command-line arguments? [duplicate]

This question already has answers here:
golang failed exec command that works in terminal
(1 answer)
How to pipe several commands in Go?
(8 answers)
Golang exec command chmod returning error
(2 answers)
Closed last year.
From my bash shell, I am able to run this following command successfully - scp <local-folder>/* <user>#<remote-host>:/var/tmp. All files in my <local-folder> are copied onto the remote location.
Now I am trying to run the above same command from my Go program, with exec.Command() but scp complains of "no such file / directory - <local-folder>/*' - the '*' is literally taken as a filename. I want to replicate the same behaviour of scp I get when I run it from my Bash shell. Here is the code snippet I am using:
pushCmd := exec.Command("scp", "<local-folder>/*", "<user>#<remote-host>:/var/tmp")
pushCmdOutput, err = pushCmd.CombinedOutput()
fmt.Fprintln(os.Stderr, string(pushCmdOutput))
Thanks in advance.

Send rm-command with $variable filename via ssh [duplicate]

This question already has answers here:
is it possible to use variables in remote ssh command?
(2 answers)
Closed 4 years ago.
in a bash script i try to do:
ssh -n $username#server2 "rm ${delete_file}"
but always get the error:
rm: missing operand
when I
> echo $delete_file
> /var/www/site/myfile.txt
I get the correct path.
What am i doing wrong?
Could it be that in your case, $delete_file is set on the remote host and not on your current machine?
If you want $delete_file to be expanded on the remote side (i.e., after ssh'ing into server2), you have to use single quotes:
ssh -n $username#server2 'rm ${delete_file}'
Other than that, do you set the value of delete_file in the same script (before ssh'ing), or before invoking your script? If latter is the case, it can't work: Variables are not propagated to scripts called by the current script/session.
You could do the following about it:
delete_file=<your-value> ./ssh-script
or:
delete_file=<your-value>
export delete_file
./ssh-script
As it turns out this last option was the problem, let me elaborate on best practices:
Better than setting environment variables would be the usage of positional parameters.
#!/bin/bash
# $1: file to delete
delete_file=${1:?Missing parameter: which file for deletion?}
ssh -n $username#server2 "rm ${delete_file}"
Usage of the script is now as simple as:
./ssh-script <your-file-for-deletion>
This way, you don't have to remember which variable is exactly expected by the script when calling it - simply call the script with a positional parameter.
As a bonus, the example uses parameter expansion to check for not-set or empty parameters:
delete_file=${1:?Missing parameter: which file for deletion?}
Whenever $1 happens to be unset or empty, the scripts exits immediately with exit code 1 and prints given message to stderr.

rsync remote to local - Unexpected remote arg [duplicate]

This question already has answers here:
How to execute a bash command stored as a string with quotes and asterisk [duplicate]
(5 answers)
Why does shell ignore quoting characters in arguments passed to it through variables? [duplicate]
(3 answers)
Closed 4 years ago.
I'm trying to assemble an rsync command in a bash variable and then execute it.
It looks something like this:
CMD="$RSYNC -a $REMOTE $LOCAL $LINK_DEST"
It gets executed like this
RSYNC_RESULT=$($CMD)
This works fine until I try to add add --rsync-path="sudo /usr/local/bin/rsync" to the mix (so that rsync runs as root on the remote).
RSYNC_PATH='--rsync-path="sudo /usr/local/bin/rsync"'
CMD="$RSYNC -a $RSYNC_PATH $REMOTE $LOCAL $LINK_DEST"
Now I get an error
Unexpected remote arg: user#remote.local:/Users/user/files/
rsync error: syntax or usage error (code 1) at main.c(1343) [sender=3.1.2]
I'm fairly certain it's connected to the quoting in the $RSYNC_PATH var and/or the $($CMD) bit, because I can paste the resulting command into a shell and it runs successfully.
Any ideas what I can do to make this work?

Bash: Set up a new command on a new line without executing [duplicate]

This question already has an answer here:
How to prefill command line input
(1 answer)
Closed 6 years ago.
I'm trying to write a BASH script to output a partially completed command which I can then add parameters to, hit ENTER and then run. I want this to be implemented completely in BASH.
e.g.
~> ./test.sh
~> ls -al <CURSOR POSITION HERE>
The only variable I've found that's close is the PROMPT_COMMAND variable, which when set inside test.sh to 'ls -al', will then immediately execute it once the script has exited.
Is there a way to stop the immediate execution, so I can add, say, *.log?
How about
read -e -p"$PWD> " -i"ls -al " cmd; eval "$cmd"

Resources