Difficulty in using sed command in ssh session in shell script in solaris - ssh

I am trying to do something like this inside ssh session:
Script
ssh remoteservername "
col=`sed -n "8p" /tmp/temp.txt`
echo $col>>/tmp/Ankur.txt
"
This is not working and it is printing empty line instead of text what I want to store in col variable, why so, and this is working:
ssh remoteservername "
sed -n "8p" /tmp/temp.txt>>/tmp/Ankur.txt
"
This Ankur.txt file is on the remote server....The main focus is how to get the output of the command inside a variable so that i can use it further.
Please tell how to make it work.
Thanks

When you use double quotes the variable names will get expanded before passing them, so $col is getting expanded locally before running on the remote server. You can either escape the $ like \$col or use single quotes around it, which is probably better since you want to use double quotes inside the command as well
ssh remoteservername '
col=`sed -n "8p" /tmp/temp.txt`
echo $col>>/tmp/Ankur.txt
'
Without changing the quotes
ssh remoteservername 'sed -n "8p" /tmp/temp.txt >> /tmp/Ankur.txt'
as you noted, still works, by redirecting the output directly into the file. This avoids the variable expansion problem from the double quotes above.
If you're going to have many steps though, you might want to just create a script on remoteservername and invoke that in your ssh command rather than doing a lot on the same command line.

You can use a local file to execute complex commands and to use variables in remote machine via SSH as shown below.
1. Create a input file 'input_file.txt'
#-- input_file.txt
col=`sed -n "8p" /tmp/temp.txt`
echo $col>>/tmp/Ankur.txt
2. Execute the commands of input file in remote server via SSH
ssh remoteservername "sh -s" < input_file.txt

Related

ssh to a server and create a directory based off a variable - all in one line

so i have a simple script that lists the folder and file structure of the current directory and spits it out to a file in the current users home directory, then rsyncs that file to a remote server into a specific folder.
the first part of the script SSH's into the remote server and creates a unique folder that the later part of the script transfers the file into.
#ssh -p 12345 sftp.domain.com ' bash -c "mkdir incoming/[foldername]" '
my question is, how can i pass a variable to this? i would usually put this in the script, and then run the script like this "copy.sh $1":
#ssh -p 12345 sftp.domain.com ' bash -c "mkdir incoming/folder-$1" '
however it doesn't work like i might hope it would. all i end up with is a folder on the remote server named "folder-" as it presumably doesn't pass the variable along with the rest when it ssh's in.
is there a better way to make this work?
the rest of the script would also reference the variable $1 to actually copy the file into the folder created on the remote server earlier in the script.
If I understand the problem correctly, the parameter you are trying to reference is set on the local client side (the command line from where you initiate the ssh connection), but you want to reference it in the command line that is to run on the remote server side. This really has nothing to do with ssh and everything to do with shell parameter/variable expansion on the local client side.
The problem is with your usage of single quotes vs. double quotes. Most Unix command shells, including bash which is likely the shell you are running on the local client side, perform environment variable expansion inside of double quotes but not inside of single quotes. So in your command line you should be able to accomplish your goal by changing the single quotes to double quotes and then escaping the embedded double quote characters like this:
#ssh -p 12345 sftp.domain.com " bash -c \"mkdir incoming/folder-$1\" "
Here is a similar example that shows this in action:
$ export EXAMPLE=abc
$ ssh localhost ' bash -c "echo $EXAMPLE def" '
def
$ ssh localhost " bash -c \"echo $EXAMPLE def\" "
abc def

How to escape $ in sed over ssh command?

I am trying to create a patch that users can use to remotely edit a file in a pre-defined way using sed, and I could do this manually on each computer, but it would take a long time.
The line I am struggling with is as follows:
host=[hostname]
port=[portnum]
ssh -t $host -p $port "cp ~/file1 ~/file1.bak ; sed -i \"s/fcn1('param1', $2)\n/fcn2('param2'):$zoom\n/g\" ~/file1"
This makes a backup of file1 and then edits a line in the file. I actually want to edit more than one line, but this line demonstrates the problems:
The command works, provided no $ signs are used within the sed command.
I have tried a number of ways of escaping these $ signs but cannot seem to find one that works.
I can use a . wildcard in the find, but obviously not in the replace string.
I would use single quotes for the sed command, in order to avoid expanding the $2, but single quotes are already used inside the command.
Does anyone have any ideas of how to overcome this problem? Thanks in advance for any suggestions!
This should work as well:
ssh -t $host -p $port "cp ~/file1 ~/file1.bak && sed -i \"s/fcn1('param1', \\\$2)/fcn2('param2'):\\\$zoom/g\" file1"
You need 3 back slashes as you have to escape the $ sign in the string passed in the remote bash to sed. And you have to escape that back slash and the $ sign when sending it over via ssh.

How can i set a local variable in ssh?

I would like to set a local variable in a ssh command-chain that is only used in this environment:
#!/bin/sh
my_var='/tmp/wrong_file'
ssh user#server "my_var='/tmp/a_file'; cat $my_var;my_var=123;echo $my_var"
echo $my_var
This example the "outer" $my_var is used. How to fix this and use variables "in" the current ssh connection as locally defined? There is no need to change or access the external value '/tmp/wrong_file' in $my_var, as asked in Assign directory listing to variable in bash script over ssh.
You're using the wrong quotes. Parameter expansion is performed inside double quotes, but not inside single quotes.
#!/bin/sh
my_var=/tmp/wrong_file
ssh user#server 'my_var=/tmp/a_file; cat $my_var;my_var=123;echo $my_var'
First of all: The SSH shell and your local shell are completely different and do not exchange any environment variables. This is a good thing - consider environment variables such as LD_LIBRARY_PATH when using SSH between machines of different OS architecture.
IMHO the best solution for your problem is to encapsulate your commands into a shell script on the remote side, then maybe start it with parameters. E.g.:
Remote:
myscript.sh contains:
#!/bin/sh
MY_FILE="$1";
echo "Contents of §MY_FILE:"
cat $MY_FILE
Local:
RUn something like
export REMOTE_FILE='/path/to/it'
ssh user#server "/path/to/myscript.sh '$REMOTE_FILE'"

Transfer files over SSH, then appended to another file

I'm trying to automate a script that copies a file from my local server to a remote server on the command line. I've done the research on scp and know how to copy the file to the remote server, but then I want to append that file to another.
This is my code:
scp ~/file.txt user#host:
ssh user#host cat file.txt >> other_file.txt
When I enter everything into the command line manually as such, everything works fine:
scp ~/file.txt user#host:
ssh user#host
cat file.txt >> other_file.txt
But when I run the script, only the file is copied, not appended to the end of other_file.txt. Help?
The second line of your code should be
ssh user#host "cat file.txt >> other_file.txt"
Three important points:
You don't want your local shell to interpret >> in any way (which it does if it's unquoted)
There is a remote shell which will interpret >> in the command correctly.
Final arguments to ssh are "joined" to form a command, not carried into an argv array as they are. It may be convenient but it also may lead to confusion or bugs: ssh cat "$MYFILE" and ssh "cat '$MYFILE'" both work in a common use case, but they both break for different values of $MYFILE.
You need to enclose the command to be run on the remote host in quotes. Otherwise, the redirection is being done locally rather than remotely. Try this instead:
scp ~/file.txt user#host:
ssh user#host 'cat file.txt >> other_file.txt'
Try this:
$ cat file.txt| ssh hostname 'cat >> other_file.txt'

How to inject commands at the start of an interactive SSH session?

I want to be able to just ssh to a server where I cannot modify profiles and set up the environment with several commands before getting the usual interactive session.
Any ideas?
I've been using an expect script with an "interact" command at the end - which works for most things but is clumsy and breaks some console apps. Also been extermienting with empty-expect and socat. Any other suggestions?
If you're able to write somewhere on the filesystem, you may be able to invoke bash with a custom rc file like this:
ssh me#example.com -t bash --rcfile /home/user/my_private_profile -i
Note that this appears to only work for interactive shell, not login shells. The -t option to ssh makes it allocate a pty even though you're specifying a command.
If you can't write to the filesystem anywhere, you could use a subshell to supply a named pipe as the rcfile:
$ ssh ares -t "bash --rcfile <(echo 'FOO=foo';echo 'BAR=bar') -i"
axa#ares:~$ echo $FOO
foo
axa#ares:~$ echo $BAR
bar