Passing arguments to a shell script to be executed within ssh - linux

I am trying to write a deployment script that will take the command I need to run on the remote machine and then run it on the remote machine. What I am envisioning is something as follows:
./DeployAndRunScript.sh "java -jar runmyjar.jar -t args &"
In my DeployAndRunScript.sh, the very last line is:
ssh -i $pemfile $targetmachine "java -jar $runcommandhere"
I was wondering, what would be a way to get the arguments from the commandline into the "runcommandline" alias and execute it within the script?

To get the arguments in a shell script you can type $#. Taking that a step further, you can simply change the last line to
ssh -i $pemfile $targetmachine "$#"
(edit: added quotes around $#, nice catch Barmar!)
You could replace $# with $1 if you know that the command will be the first argument wrapped in quotes.

Related

how to execute ssh comand on .sh file?

I trying to create a .sh file that execute things like "pwd" or "ls" command.
My problem its when i execute the .sh file.
Its seems not recognize the tasks
I tried to use echo
Example : echo 'lsApps' or echo "lsApps"
but it prints the name of the task instead execute the comand
for example i want to execute a .ssh file that makes a pwd
VAR_1=pwd
echo $VAR_1
but it prints me pwd instead the current path ...
Any idea?
echo is used to print on the screen (man page reference). If you do echo 'IsApps' it will take it as a string and print it. If you want to execute a command you can just do it by doing IsApps (acutes not quotes, acute is usually below the escape key). This will execute the command and show the output on the screen. If you want to store the output of the command in a variable, you can do
<variable_name>=`IsApps`
This will store the output in the variable. Note that there is no space between variable name and the command. Also, those are not quotes but instead acutes. To print the variable on screen you can use echo by doing echo $<variable_name>
If you don't want to see the output at all. You can do
IsApps > /dev/null
this will execute the command but you will not see any stdout on your screen.
As far as ssh is concerned, do ssh-keygen and then ssh-copy-id user#remote_ip to set ssh keys so that you don't have to enter your password with ssh. Once you have done that, you can use ssh user#remote_ip in your shell script.

Having trouble with running a command over ssh

This command isn't working as expected:
ssh root#<machineIP> -- sh -c "echo \$\(cat /tmp/testfile\) > /testfile"
My intent is to copy the contents of /tmp/testfile to /testfile. Real simple. But I find that /testfile has nothing in it. The file is created (in the case it doesn't exist).
echo command works fine (minus the escapes) if run from command line on the remote server. But doesn't work when running it through ssh. Originally I actually had a more complex command with 'sed', but simplified what wasn't working down to this.
Both remote and local servers are CentOS7.
I found I had to escape the $ and (). Is this causing me problems? Is not the correct way to run this command?
ssh will take all the command parameters, join them on spaces and then run that in the remote shell.
That means that the command being executed is basically what you'd get if you replaced ssh with echo:
$ echo sh -c "echo \$(cat /tmp/testfile) > /testfile"
sh -c echo $(cat /tmp/testfile) > /testfile
The quoting is lost, so the resulting command is equivalent to sh -c echo > /testfile which makes it empty.
Instead, just take the command you want to run and wrap it in single quotes:
ssh root#host 'echo $(cat /tmp/testfile) > /testfile'
Make sure never to use echo or $() when copying files though. I'm assuming this is a stand-in for something better.

Unix Shell Script With Command Arguments To Open Another Program With Those Arguments

I have the following Unix Shell Script. I'm am accepting arguments to the shell correctly. I'm trying to take those arguments and running the ./TCPHost.out program.
This ./TCPHost.out program takes two command line arguments to successfully run. I need to get those arguments from the execution of the shell, and pass them to the TCPHost.out COMMAND1 COMMAND2.
I am receiving the following error (Makes sense because it believes it's a file, not a file to be ran with arguments):
Error In Terminal: The file /Users/71021180/Desktop/Murph Chat Assignment/TCPHost.out 127.0.0.1 5001 does not exist.
Can someone explain this better to me? I'm new to Unix Shell Scripting.
#!/bin/bash
echo Hello World
echo Total Number of Argument Passed: "$#"
echo Arguments List -
echo $1
echo $2
open -a Terminal ./TCPServer.out
open -a Terminal ./TCPHost.out" "$1" "$2
open -a Terminal ./TCPClient.out

How to pass local variable to remote ssh commands?

I need to execute multiple commands on remote machine, and use ssh to do so,
ssh root#remote_server 'cd /root/dir; ./run.sh'
In the script, I want to pass a local variable $argument when executing run.sh, like
ssh root#remote_server 'cd /root/dir; ./run.sh $argument'
It does not work, since in single quote $argument is not interpreted the expected way.
Edit: I know double quote may be used, but is there any side effects on that?
You can safely use double quotes here.
ssh root#remote_server "cd /root/dir; ./run.sh $argument"
This will expand the $argument variable. There is nothing else present that poses any risk.
If you have a case where you do need to expand some variables, but not others, you can escape them with backslashes.
$ argument='-V'
$ echo "the variable \$argument is $argument"
would display
the variable $argument is -V
You can always test with double quotes to discover any hidden problems that might catch you by surprise. You can always safely test with echo.
Additionally, another way to run multiple commands is to redirect stdin to ssh. This is especially useful in scripts, or when you have more than 2 or 3 commands (esp. any control statements or loops)
$ ssh user#remoteserver << EOF
> # commands go here
> pwd
> # as many as you want
> # finish with EOF
> EOF
output, if any, of commands will display
$ # returned to your current shell prompt
If you do this on the command line, you'll get a stdin prompt to write your commands. On the command line, the SSH connection won't even be attempted until you indicate completion with EOF. So you won't see results as you go, but you can Ctrl-C to get out and start over. Whether on the command line or in a script, you wrap up the sequence of commands with EOF. You'll be returned to your normal shell at that point.
You could run xargs on the remote side:
$ echo "$argument" | ssh root#remote_server 'cd /root/dir; xargs -0 ./run.sh'
This avoids any quoting issues entirely--unless your argument has null characters in it, I suppose.

What does the -b argument do in csh?

I am looking at a tcsh script that has the following shebang line:
#!/bin/tcsh -fb
# then executes some commands
What does the -b do?
From the man page:
-b Forces a ''break'' from option processing, causing any further shell arguments to
be treated as non-option arguments. The remaining arguments will not be inter-
preted as shell options. This may be used to pass options to a shell script with-
out confusion or possible subterfuge. The shell will not run a set-user ID script
without this option.
But I don't really understand what it means...
An example would be great.
Thanks.
Say, for example, you have a script that is named --help and you want to execute it using tcsh:
tcsh --help
This will obviously not work. The -b forces tcsh to stop looking for arguments and treat the rest of the command line as file names or arguments to scripts. So, to run the above weirdly named script, you could do
tcsh -b --help

Resources