cygwin: vagrant ssh, empty command prompt - vagrant

If I vagrant ssh with windows cmd, I get a nice command prompt, like that:
vagrant#homestead:~$ echo foo
vagrant#homestead:~$ foo
But with cygwin and mintty, I have no prompt at all:
echo foo
foo
I see it has to do with "pseudo-tty allocation".
With cygwin and mintty, I can have my prompt with this :
vagrant ssh -- -t -t
How can I change cygwin and mintty so that I don't have to tell the -t ?
About the ssh -t option :
"Force pseudo-tty allocation. This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g., when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty."

I had the same problem with and the solution was to set the VAGRANT_PREFER_SYSTEM_BIN environment variable to get vagrant to use your normal ssh executable.
You can do:
VAGRANT_PREFER_SYSTEM_BIN=1 vagrant ssh
or put this into your .bash_profile:
export VAGRANT_PREFER_SYSTEM_BIN=1
Reference: https://github.com/hashicorp/vagrant/issues/9143#issuecomment-343311263

I run in the same problem described above. But only on one of three PCs. But as a workaround I am doing:
# save the config to a file
vagrant ssh-config > vagrant-ssh
# run ssh with the file.
ssh -F vagrant-ssh default
From an answer of How to ssh to vagrant without actually running "vagrant ssh"?
In this case I am getting the prompt and what's more important also history cycling and ctrl-c etc. are working properly.

Vagrant is a windows program managing Virtual machine
https://www.vagrantup.com/intro/index.html
as such it does not well interface with the pseudo tty
structure used by cygwin programs.
Read for reference on similar issues with a lot of other windows program
https://github.com/mintty/mintty/issues/56
Mintty is a Cygwin program. It expect interactive program running inside it to use the cygwin tty functionality for interactive behaviour.
Running Vagrant from Bash in Windows CMD, make CMD the terminal control so Vagrant has no problem in the interactive behaviour.
I do not see the need to run Vagrant inside Cygwin

Since vagrant is windows-based, I use ConEmu instead of cygwin's shell (mintty)
choco install conemu via chocolatey and it works

General solution is to teach vagrant to use ssh, compatible with preferred terminal. Like Cygwin ssh+mintty.
Modern Vagrant (v2.1.2) has VAGRANT_PREFER_SYSTEM_BIN=1 by default on Windows.
To troubleshoot issue:
VAGRANT_LOG=info vagrant ssh
In v2.1.2 they broke Cygwin support. See my bug report with hack to lib/vagrant/util/ssh.rb to make it work.

Related

How to launch WSL as if I've logged in?

I have a WSL Ubuntu distro that I've set up so that when I login 4 services start working, including a web API that I can test via Swagger to verify it is up and working.
I'm at the point where what I want to do now is start WSL via a script - that is, launch my distro, have all of the services start, and do it from Python. The problem is I cannot even figure out the correct syntax to get WSL to start from PowerShell in a manner where my services start.
Side note: "services" != systemctl (or similar) calls, but just executing bash CLI commands from either my .bashrc or .profile at login.
I've put the commands to execute in .profile & .bashrc. I've configured it both for root execution and non-root user execution. I've taken the commands out of those 2 files and put it into a script in the Windows file system that I pass in on the start of wsl. And I've put that shell script in the WSL file system as well. Nothing seems to work, and sometimes the distro starts and then stops after about 30 seconds.
Some of the PS CLI commands I've tried:
Start-Job -ScriptBlock{ wsl -d distro -u root }
Start-Job -ScriptBlock{ wsl -d distro -u root 'bash -i -l -c /root/bin/start.sh'
Start-Job -ScriptBlock{ wsl -d distro -u root 'bash -i -l -c .\start.sh'
wsl -d distro -u root -- bash -i -l -c /root/bin/start.sh
wsl -d distro -u root -- bash -i -l -c .\start.sh
wsl -d distro -u root -- /root/bin/start.sh
Permutations of the above that I've tried: replace root with my default login, and turning all of the Start-Job bash options into a comma-separated list of single-quoted strings (Ex: 'bash', '-i', '-l', ... ). Nothing I launch from the CLI will allow me access to the web API that is supposed to be hosted on my distro.
Any advice on what to try next?
Not necessarily an answer here as much as troubleshooting tips which will hopefully lead to an answer:
First, most of the forms that you are using seem to be correct. The only ones that absolutely shouldn't work are those that attempt to run the script from the Windows filesystem.
Make sure that you have a shebang line starting your script. I'm assuming you do, but other readers may come across this as well. For the moment, try this form:
#!/usr/bin/env -S bash -li
That's going to have the same effect as the bash -li you tried -- It will source both both interactive startup files such as ~/.bashrc as well as login profiles such as ~/.bash_profile (and /etc/profile.d/*, etc.).
Note that preferably, you won't need the -li. Best practice would be to move anything necessary for the services over from the startup scripts to your start.sh script, and avoid parsing the profile and rc. I need to go update some of my answers, since I just realized I've been guilty of giving some potentially bad advice ...
Specifically, though, I'm wondering if your interactive Bash config has something truly, well, "interactive" in it that might be preventing the automatic running of the script itself. Again, best practice would be for ~/.bashrc to only hold configuration that is needed for interactive shell sessions.
Make sure the script is set as executable (chmod +x start.sh). Again, I'm assuming this is the case for you.
With a shebang line and an executable script, use something like:
wsl -d distro -u root -e /root/bin/start.sh
The -e tells WSL to launch the script directly. Since it has a shebang line, it will be parsed by Bash. Most of the other forms you use above actually run Bash twice - Once when launching WSL and another when it finds the shebang line in the script.
Try some basic troubleshooting for your script like:
Add set -x to the top (right under the shebang line) to turn on script debugging.
Add a ps -efH at the end to show the processes that are running when the script completes
If needed, resort to quick-and-dirty echo statements to show where things have progressed in the script.
I'm hopeful that the above will at least show you the problem, but if not, add the debugging info that you gain from this to your question, and we can troubleshoot further.

A Bash script which runs commands in two terminal / ssh sessions

I'm trying to automate setting up and configuring a vagrant process with a bash script.
The thing is, I need to to ssh into my vagrant machine twice, and I want both terminals to be visible on my screen whilst doing this.
The process is like so...
In terminal 1:
vagrant up
vagrant ssh myhost
wait
cd /my/directory/
... do some commands...
Then I want this terminal to persist / stay open, and a new tab to open where another vagrant session starts
wait
cd /my/other/directory
.... do some commands...
I've got the script working for the first vagrant/terminal session and stored in my /bin/ directory, but how do I add the second?
How it looks exactly depends on the terminal emulator, but the basic pattern could be as follows:
First script (script1.sh)
vagrant up
vagrant ssh myhost
wait
cd /my/directory/
xterm -e script2.sh &
... do some commands...
Second script (script2.sh)
wait
cd /my/other/directory
.... do some commands...
The trick is to open another terminal window from the first script (for xterm its xterm -e).
In case you are interested in a way that works indepedently of the terminal emulator, consider using tmux (terminal multiplexer).
Other general hint: It is generally not recommended to store locally-created scripts under /bin. A more common place would be /usr/local/bin or $HOME/bin (although $HOME/bin might need to be configured separately).

Automating tasks after vagrant ssh

Wondering if it is possible to automatically run a script or execute a command ONLY after vagrant ssh into the box? I understand that Ansible can provide beforehand installation and set up. But it failed to allow doing things automatically after entering the machine.
I am currently create a file script.sh. The file will be provided to the vagrant via Ansible. After I vagrant ssh into the box, I do bash script.sh to run the script. Is there better way?
Any suggestion would be more appreciated.
Two ways to achieve this,
Say assume your script is in vagrant home directory like,
:~$/home/vagrant/test-me.sh
1) Run command along with ssh
1a) vagrant ssh -- -t '/home/vagrant/test-me.sh; /bin/bash'
**-OR-**
1b) vagrant ssh -c '/home/vagrant/test-me.sh; /bin/bash'
2) Append complete script path in ~/.bashrc file (this should be in vagrant home directory if you are login as user vagrant)
:~$echo '. /home/vagrant/test-me.sh' >> ~/.bashrc

bash-completion (from Homebrew) not completing variables on OSX

I use bash completion all the time to save typing. However there is an oddity I am unable to figure out how to fix on OSX.
If I install bash-completion using Homebrew (brew install bash-completion) and set it up in .bashrc, the tab key will no longer complete environment variables. Without this installed, environment variable completion works as expected.
For example, I have shortcuts for all my SSH accounts for clients... instead of typing ssh myuser#somecrazydomain.com I can just type ssh $SSHCRAZY which is much easier to remember.
Expected behavior: In the built-in bash in OSX I can type ssh $SSHC and hit tab and it completes to the full command as expected. This is what I want.
Observed behavior: In bash using the homebrew bash-completion additions, hitting tab has no effect for environment variables.
Note: All other extensions added by the bash-completion project are desired (git command completion, etc). I don't want to uninstall it, I just want it to also work with environment variables.
Thanks in advance for any help!
You might consider using an SSH config file (~/.ssh/config) to set up your SSH shortcuts instead of using environment variables. You could put into that file:
Host crazy
HostName somecrazydomain.com
User myuser
Then you can just type ssh crazy.
I guess bash-completion must have defined completion rule for ssh. So try add the -o bashdefault option in your .bashrc. For example, if complete -p ssh output like this:
# complete -p ssh
complete -F _func ssh
#
then you can add this to your .bashrc (or .bash_profile):
complete -F _func -o bashdefault ssh
or
eval "$(complete -p ssh | sed 's/ssh$/-o bashdefault ssh/')"

Can't run chef-solo command through ssh

In the case when I first ssh to the server and then run command, it executes successfully
root#chef:~# chef-solo -v
Chef: 11.10.0
But when I try to run it like this
ssh root#188.xxx.xxx.xxx -t -C "chef-solo -c /var/chef/solo.rb"
I receive an error:
bash: chef-solo: command not found
Why is this happening, and how can I solve this issue ?
It is still matter of $PATH and ssh - not chef-solo. Interactive and non-interactive sessions not necessarily have same value for the $PATH variable. Same ssh problem is described here on stackoverflow. You may also check GNU bash manual to have deeper insight of (non-)interactive and (non-)login shells. To shorten, solution would be one of the following:
Run chef-solo using absolute path. Here's how your command might look like:
ssh root#188.xxx.xxx.xxx -t -C "/usr/local/ruby/bin/chef-solo -c /var/chef/solo.rb"
Tune the .bash configuration files to load same $PATH variable for both interactive and non-interactive shells.
Note: To find out what's the absolute path, login to the machine via ssh and run which chef-solo (Don't know how experienced you are with linux. Sorry if I'm underestimating your knowledge)

Resources