Powershell issue - executing command in Git Bash - bash

I'm trying to write a script that's part of a much bigger automation script that configures the GitHub ssh key on a local dev machine.
This is the line I'm trying to run but for some reason the 'eval $(ssh-agent -s)' fails as it errors and outputs this message.
'eval' is not recognized as an internal or external command,
operable program or batch file.
cmd.exe /c "ssh-keygen -t rsa -b 4096 -C "$githubEmailAddress" && eval $(ssh-agent -s) && ssh-add ~/.ssh/id_rsa && clip < ~/.ssh/id_rsa.pub"
I have looked around and I'm having no luck getting past this issue. I can't work out how to launch the Git Bash terminal where the command works from the ps1 script.

You should consider creating an alias for bash.exe that way it is only referenced one time in the script and will be easier to change if you need to in the future.
You can then create the SSH key as shown:
New-Alias -Name gitBash -Value "$Env:ProgramFiles\Git\bin\bash.exe
gitBash -c "ssh-keygen -t rsa -b 4096 -C "blah#gmail.com" && eval $(ssh-agent -s) && ssh-add ~/.ssh/id_rsa && clip < ~/.ssh/id_rsa.pub && exit"
You also won't have to do as much encoding as the key gen parameters won't need to be wrapped in a string delimiter anymore.
You also avoid managing the current directory manually like you are with the cd command.
Also note the use of the $Env:ProgramFiles to get the base path of the program files directory, its not common for it to be configured differently than "C:\Program Files" but it can be and it avoids issues with spaces in the path name this way.

After a lot of trial and error the way you can open a git bash prompt from powershell is to find the bin\bash.exe file normally found in a folder called Git within the Program Files folder.
From the location of the ps1 file you might need to modify the ....\ part but the script below allow you to open a bash prompt execture a bunch of calls and then exit the prompt
cmd.exe /c 'cd "..\..\Program Files\Git\bin" && bash.exe -c "ssh-keygen -t rsa -b 4096 -C "blah#gmail.com" && eval $(ssh-agent -s) && ssh-add ~/.ssh/id_rsa && clip < ~/.ssh/id_rsa.pub && exit"'

Related

Bash remote ssh command is not working because of premature expansion

I'm trying to delete the contents of a remote directory in a bash script and leaving the folder intact by using ssh like this:
# First attempt
inboxResult=$(ssh -t -t username#host sudo -u rootUser rm -Rf /my/path/here/inbox/*)
# Second attempt
inboxResult=`ssh -t -t username#host sudo -u rootUser rm -Rf /my/path/here/inbox/*`
but it keeps failing silently. I've done my research and it seems like the '*' is being expanded before the command is sent via ssh to the remote host, but I would want the opposite. I couldn't find any solution and I've tried more than these two but they seem to be far from what I was looking.

Execute multiple commands on remote server using bash

I want to execute cd and scp commands on a remote server which have to be logged in with a different sudo user. Below code snippet asks for the password(echos on screen) for my user but hangs there. It doesn't execute cd
#!/bin/bash
server=myserver.com
ssh $server 'sudo -S -u <user> -i; cd dir1/dir2/; scp file1 user#local-sever'
The issue is that you have a semi colon before cd and so sudo has no command to execute. Remove the ; and it should work:
ssh $server 'sudo -S -u <user> -i scp dir1/dir2/file1 user#local-sever'
There are several ways to address this, but most boil down to wrapping up the commands into a set of instructions. Raman's solution is good since it handles the issue by using full paths, but sometimes that isn't an option. Here's another take -
Assuming your command list can afford the quotes, I like here-strings.
ssh -t sa-nextgen-jenkins.eng.rr.com <<< "
echo 'set -x; cd /tmp; whoami; touch foo; ls -l foo; rm -f foo;'|sudo -iSu user
"
If you need the quotes, try a here-doc.
ssh -t sa-nextgen-jenkins.eng.rr.com <<END
echo 'set -x; echo "$RANDOM"; cd /tmp; whoami; touch foo; ls -l foo; rm -f foo;'|sudo -iSu $user
END
You can also write a small script that has arbitrarily complex commands and scp it over, then use a remote ssh call to execute it as the relevant user.

generating SSH key for github: "zsh: command not found: $"

I'm trying to configure github with my macOS system. I use iTerm and zsh. When I try to generate a new ssh key according to the instructions from the https://help.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key I get an error "zsh: command not found: $". Please help.
$ is what you see in sh. In zsh you probably see [path#user] $ or something like that. You just mustn't copy this dollar sign. What you copy should by ONLY:
ssh-keygen -t rsa -b 4096 -C "your_email#example.com"
Runing it in bash instead works for me
exec bash
then
ssh-add -K ~/.ssh/id_ed25519
And you can switch back to zsh by
exec zsh
avoid copying dollar sign while generation ssh keys.
use this ----> ssh-keygen -t rsa -b 4096 -C "your_email#example.com"

ssh server bash -c "cd /tmp && git pull" , cd does not work, need to add echo first

I'm on ubuntu 15.04, my version of ssh client is
OpenSSH_6.9p1 Ubuntu-2ubuntu0.2, OpenSSL 1.0.2d 9 Jul 2015
When I try to run the following command ssh admin#server bash -c 'cd /path/to/repo && git pull' the cd is not effective and i got
fatal: Not a git repository (or any of the parent directories): .git
However If I do
ssh admin#server bash -c 'echo test && cd /path/to/repo && git pull'
then it works
Already up-to-date.
Of course I'm well aware echo is not supposed to change anything but after trying several time, several days on several different servers (though all on debian) I'm now sure to have this error.
On other servers I tried the command cd /tmp && pwd , and I got my home directory, and if i do echo toto && /tmp && pwd I go /tmp printed...
Unfortunately, ssh passes through a single command line string to $SHELL -c on the remote. Your quotes aren't being effective.
When you run
ssh admin#server bash -c 'cd /path/to/repo && git pull'
this is being run on the remote server (with $SHELL -c):
bash -c cd /path/to/repo && git pull
So Bash is given single command (cd) and an unused argument, and then separately, you're also running git pull in the home directory.
On the other hand, when you run
ssh admin#server bash -c 'echo test && cd /path/to/repo && git pull'
this is being run on the remote server:
bash -c echo test && cd /path/to/repo && git pull
The first part is again useless, but the shell running the whole command then does cd /path/to/repo and git pull. Which works.
What you probably want to do is
ssh admin#server 'cd /path/to/repo && git pull'
The existing answer by ephemient is entirely correct in terms of cause.
To add an alternate solution -- one which works when your remote code contains constructs which sh -c will misinterpret -- consider:
repo=/path/to/repo ## here, this works even when your path contains
## nonprintable or otherwise surprising characters
printf -v repo_q '%q' "$repo" ## ...because we're asking your local copy of bash
## to generate a quoted/escaped copy of the value
## that will 'eval' back to its original meaning
## when interpreted by bash
## to ensure that it's interpreted by bash, we pass 'bash -s' as the command to ssh
## with an *unquoted* heredoc (<<EOF, vs <<'EOF'), with the escaped value expanded
ssh admin#server 'bash -s' <<EOF
cd $repo_q && git pull
EOF

How can I execute a script from my local machine in a specific (but variable) directory on a remote host?

From a previous question, I have found that it is possible to run a local script on a remote host using:
ssh -T remotehost < localscript.sh
Now, I need to allow others to specify the directory in which the script will be run on the remote host.
I have tried commands such as
ssh -T remotehost "cd /path/to/dir" < localscript.sh
ssh -T remotehost:/path/to/dir < localscript.sh
and I have even tried adding DIR=$1; cd $DIR to the script and using
ssh -T remotehost < localscript.sh "/path/to/dir/"
alas, none of these work. How am I supposed to do this?
echo 'cd /path/to/dir' | cat - localscript.sh | ssh -T remotehost
Note that if you're doing this for anything complex, it is very, very important that you think carefully about how you will handle errors in the remote system. It is very easy to write code that works just fine as long as the stars align. What is much harder - and often very necessary - is to write code that will provide useful debugging messages if stuff breaks for any reason.
Also you may want to look at the venerable tool http://en.wikipedia.org/wiki/Expect. It is often used for scripting things on remote machines. (And yes, error handling is a long term maintenance issue with it.)
Two more ways to change directory on the remote host (variably):
echo '#!/bin/bash
cd "$1" || exit 1
pwd -P
shift
printf "%s\n" "$#" | cat -n
exit
' > localscript.sh
ssh localhost 'bash -s "$#"' <localscript.sh '/tmp' 2 3 4 5
ssh localhost 'source /dev/stdin "$#"' <localscript.sh '/tmp' 2 3 4 5
# make sure it's the bash shell to source & execute the commands
#ssh -T localhost 'bash -c '\''source /dev/stdin "$#"'\''' _ <localscript.sh '/tmp' 2 3 4 5

Resources