unexpected EOF while looking for matching `"' - linux

The command works fine when I execute from command line. However It throws an error when I execute it from shell script
rsync -avz -e ssh --exclude-from=rsync.file --rsync-path="sudo rsync" ostnfe/ ubuntu#mask.compute-1.amazonaws.com:/var/www/ostnfe
Code from shell script:
CMD='rsync -avz -e ssh --exclude-from=rsync.file --rsync-path="sudo rsync" '$1'/ ubuntu#'$AMZ':/var/www/'$2
$CMD
error:
bash: -c: line 0: unexpected EOF while looking for matching `"'
bash: -c: line 1: syntax error: unexpected end of file

You could just use a shell function instead:
cmd () {
rsync -avz -e ssh --exclude-from=rsync.file --rsync-path="sudo rsync" $1/ ubuntu#$AMZ:/var/www/$2
}
# calling with args
cmd "$1" "$2"
# alternatively, calling through variable without args
VAR='eval cmd "$1" "$2"'
$VAR
Less hassle with escaping this way.
Update: Edited cmd() to represent the working solution.

Bad idea to store full command line in a string. Use BASH arrays instead:
CMD=(rsync -avz -e ssh --exclude-from=rsync.file "--rsync-path='sudo rsync'" "$1/ ubuntu#$AMZ:/var/www/$2")
"${CMD[#]}"

Please try following:
CMD=$(echo "rsync -avz -e ssh --exclude-from=rsync.file --rsync-path=\"sudo rsync\" $1/ubuntu#${AMZ}:/var/www/$2")
$CMD
check for any missing or extra space.

Related

Using escape characters inside double quotes in ssh command in bash script

I want to run some commands each time when I log in to a remote system. Storing commands in .bashrc on remote is not an option.
What is the proper way to escape the escape chars inside of quotes in bash script for ssh?
How can I write each command in new line?
My script
#!/bin/bash
remote_PS1=$'\[\033[01;32m\]\u#\[\033[03;80m\]\h\[\033[00m\]:\[\033[01;34m\]\!:\w\[\033[00m\]\$ '
ssh -t "$#" 'export SYSTEMD_PAGER="";' \
'export $remote_PS1;' \
'echo -e "set nocompatible" > /home/root/.vimrc;' \
'bash -l;'
didn't work.
Escaping escape characters inside double-quotes and run them on remote server is way too complicated for me :)
Instead, I wrote a remoterc file for remote and a small remotessh script.
In remotessh, first I copy remoterc on remote machine and run bash command with that remoterc file interactively.
remoterc:
#!/bin/bash
SYSTEMD_PAGER=""
PS1="\[\033[01;32m\]\u#\[\033[03;80m\]\h\[\033[00m\]:\[\033[01;34m\]\!:\w\[\033[00m\]\$ "
echo -e "set nocompatible" > /home/root/.vimrc
remotessh:
#!/bin/bash
scp remoterc "$1":/home/root/
ssh "$1" -t "bash --rcfile remoterc -i"
It works :)
You can use Bash's printf %q.
According to help printf:
%q      quote the argument in a way that can be reused as shell input
See the following example:
$ cat foo.sh
ps1='\[\033[1;31m\]\u:\w \[\033[0m\]\$ '
ps1_quoted=$( printf %q "$ps1" )
ssh -t foo#localhost \
'export FOO=bar;' \
"export PS1=$ps1_quoted;" \
'bash --norc'
Result:

smbclient: command not found

I would like to connect to a remote server with the smbclient command and pass some arguments to the script.
Here is my command:
smbclient //$SERVER -c 'cd $PATH;get $FILE /tmp/$FILE' $PASS -U$PSEUDO -W domain
When I launch this command without variables on the command line it works. But when I use it in the script it says:
./test1.sh: line 14: smbclient: command not found
Why is that?
Here is my complete script with for exemple arguments testSRV, testPATH and testFile :
\#! /bin/bash
SERVEUR=$1
PATH=$2
FILE=$3
echo $PATH #Return testPATH
echo $FILE #Return testFILE
\#COMPLETEPATH="cd $testPATH;get $testFILE /tmp/$testFILE"
\#echo $COMPLETEPATH //return
/usr/bin/smbclient //$SERVER -c 'cd $PATH;get $FILE' testpassword -U testuser -W testdomain
It's good,
Thanks you all but I achieved to make my script works.
I tried to replace single quote with double quote and put the full command path
You have two options: ensure /usr/bin is on your PATH (echo $PATH to see if this is the case) or edit the script to call smbclient with the full path (/usr/bin/smbclient)

How to log non-interactive bash command sent through ssh

I'm sending a command through ssh:
ssh server.org 'bash -s' << EOF
ls -al
whoami
uptime
EOF
How to log it in the system (remote server)? I'd like to log those commands in some file (.bash_history or /tmp/log).
I've tried to add the line below to sshd_config:
ForceCommand if [[ -z $SSH_ORIGINAL_COMMAND ]]; then bash; else echo "$SSH_ORIGINAL_COMMAND" >> .bash_history; bash -c "$SSH_ORIGINAL_COMMAND"; fi
But it logs "bash -s" only.
I'll appreciate any help.
When bash shell exits, bash reads and executes commands from the ~/.bash_logout file. Probably you can run the history command at the end in the .bash_logout(of the server) and save it to some location.
If it suffices to work with the given command, we can put the necessary additions to enable and log command history at the beginning and end, e. g.
ssh server.org bash <<EOF
set -o history
ls -al
whoami
uptime
history|sed 's/ *[0-9]* *//' >>~/.bash_history
EOF
Or we could put them into the awfully long ForceCommand line:
… if [[ "$SSH_ORIGINAL_COMMAND" == bash* ]]; then echo "set -o history"; cat; echo "history|sed 's/ *[0-9]* *//' >>~/.bash_history"; else cat; fi | bash -c "$SSH_ORIGINAL_COMMAND"; fi

Bash Script Variable

#!/bin/bash
RESULT=$(grep -i -e "\.[a-zA-z]\{3\}$" ./test.txt)
for i in $(RESULT);
do
echo "$i"
FILENAME="$(dirname $RESULT)"
done
I have a problem with the line FILENAME="$(dirname $RESULT)". Running the script in debugging mode(bash -x script-name), the ouput is:
test.sh: line 9: RESULT: command not found
For some reason, it can't take the result of the variable RESULT and save the output of dir command to the new variable FILENAME. I can't understand why this happens.
After lots of tries, I found the solution to save full path of finame and finame to two different variables.
Now, I want for each finame, find non-case sensitive of each filename. For example, looking for file image.png, it doesn't matter if the file is image.PNG
I am running the script
while read -r name; do
echo "$name"
FILENAME="$(dirname $name)"
BASENAME="$(basename $name)"
done < <(grep -i -e "\.[a-zA-z]\{3\}$" ./test.txt)
and then enter the command:
find . $FILENAME -iname $BASENAME
but it says command FILENAME and BASENAME not found.
The syntax:
$(RESULT)
denotes command substitution. Saying so would attempt to run the command RESULT.
In order to substitute the result of the variable RESULT, say:
${RESULT}
instead.
Moreover, if the command returns more than one line of output this approach wouldn't work.
Instead say:
while read -r name; do
echo "$name"
FILENAME="$(dirname $name)"
done < <(grep -i -e "\.[a-zA-z]\{3\}$" ./test.txt)
The <(command) syntax is referred to as Process Substitution.
for i in $(RESULT) isn't right.You can use $RESULT or ${RESULT}

sed not working on remote machine

I'm trying to run a script on a remote server like so:
ssh root#cnc-02 'bash -c "
echo $SHELL;
cd /home/bldadmin/patch;
pwd;
echo '$int_ver_cnc';
echo '$rev_ver_cnc';
echo '$pre_ver_cnc';
cp -Rf RP_'$pre_ver_cnc'-'$int_ver_cnc' RP_'$int_ver_cnc'-'$rev_ver_cnc';
cd /home/bldadmin/patch/RP_'$int_ver_cnc'-'$rev_ver_cnc'/CSCONsap/data/twoway/manual;
rm rulePkg.zip;
mv cncrules-CNC60Test-1.48.0-1.49.0.zip rulePkg.zip;
cd /home/bldadmin/patch/RP_'$int_ver_cnc'-'$rev_ver_cnc';
find . -name install.sh.orig;
sed -e 's/^\(patchid=\)\(.*\)/\1\"1.47.0-1.48.0\"/g' -e 's/^\(fromVersion=\)\(.*\)/\1\"1.47.0\"/g' -e 's/^\(toVersion=\)\(.*\)/\1\"1.48.0\"/g' install.sh.orig >newfile.sh.orig;
"'
This is my script on my local machine. It will SSH to a remote machine and execute a list of commands. All the commands are executing but sed is not working. I'm getting the below error
"bash: -c: line 14: syntax error near unexpected token `(' bash: -c:
line 14: ` sed -e s/^(patchid=)(.*)/11.47.0-1.48.0/g -e
s/^(fromVersion=)(.*)/11.47.0/g -e s/^(toVersion=)(.*)/11.48.0/g
install.sh.orig >newfile.sh.orig;' "
The sed command when executed locally is working fine, I don't know what I am missing?
Instead of getting in a quoting headache save your script into a file script.sh
(use a sensible descriptive name) and run:
$ ssh root#cnc-02 'bash -s' < script.sh

Resources