Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stdin: is not a tty #1673

Closed
geoffroymontel opened this issue Apr 30, 2013 · 51 comments
Closed

stdin: is not a tty #1673

geoffroymontel opened this issue Apr 30, 2013 · 51 comments

Comments

@geoffroymontel
Copy link

@geoffroymontel geoffroymontel commented Apr 30, 2013

Hello

I run Vagrant version 1.2.2 on Mac OS 10.8.3.

When I set up a multi VM environment with lucid64 boxes, which I provision either with shell or puppet, I always get the following error when provisionning

stdin: is not a tty

Example :

dhcp-10-0-89-123:devops-test-deploy geoffroy$ vagrant up test
Bringing machine 'test' up with 'virtualbox' provider...
[test] Importing base box 'precise64'...
[test] Matching MAC address for NAT networking...
[test] Setting the name of the VM...
[test] Clearing any previously set forwarded ports...
[test] Creating shared folders metadata...
[test] Clearing any previously set network interfaces...
[test] Preparing network interfaces based on configuration...
[test] Forwarding ports...
[test] -- 22 => 2250 (adapter 1)
[test] -- 80 => 4567 (adapter 1)
[test] Running any VM customizations...
[test] Booting VM...
[test] Waiting for VM to boot. This can take a few minutes.
[test] VM booted and ready for use!
[test] Setting hostname...
[test] Configuring and enabling network interfaces...
[test] Mounting shared folders...
[test] -- /vagrant
[test] -- /etc/puppet
[test] -- /tmp/vagrant-puppet/manifests
[test] Running provisioner: shell...
[test] Running: /var/folders/6m/twgys53s1cn326fz4tlrchjr0000gn/T/vagrant-shell20130430-3314-ejk9pk
stdin: is not a tty

Thanks

Geoffroy

@mitchellh
Copy link
Member

@mitchellh mitchellh commented Apr 30, 2013

Yeah this is a known "thing." It is not really a problem because it doesn't really cause a problem. Actually, the reason this error message even appears is due to a bug in Ubuntu not checking whether stdin is a TTY, and just assuming it is.

@mitchellh mitchellh closed this Apr 30, 2013
@geoffroymontel
Copy link
Author

@geoffroymontel geoffroymontel commented May 1, 2013

thanks for your quick reply ! I won't bother then :)

@bradfeehan
Copy link

@bradfeehan bradfeehan commented Jun 29, 2013

Is there any workaround possible to avoid this warning? For some reason it annoys me unnaturally 😄

@pencilcheck
Copy link

@pencilcheck pencilcheck commented Jul 7, 2013

Yea, along with occasional dpkg-preconfigure: unable to re-open stdin: No such file or directory is making me nervous

@cebutech
Copy link

@cebutech cebutech commented Aug 27, 2013

Is this also something to not worry about? dpkg-preconfigure: unable to re-open stdin: No such file or directory

@andyshinn
Copy link

@andyshinn andyshinn commented Sep 13, 2013

For those looking for a fix, see https://bugs.launchpad.net/ubuntu/+source/xen-3.1/+bug/1167281. I recently built my own box using veewee and replaced:

msg n

With:

tty -s && mesg n

In file /root/.profile.

@johnraz
Copy link

@johnraz johnraz commented Oct 19, 2013

Adding this to a shell provisioner should fix it:
sed -i 's/^mesg n$/tty -s \&\& mesg n/g' /root/.profile

@kpassapk
Copy link

@kpassapk kpassapk commented Oct 23, 2013

@johnraz , thanks for that 👍

@phirschybar
Copy link

@phirschybar phirschybar commented Oct 25, 2013

@johnraz that worked for me too on one host machine but on another host machine I now get:

tty: extra operand 'mesg'

@johnraz
Copy link

@johnraz johnraz commented Oct 25, 2013

It's really a nasty hack anyway and I only tried it against ubuntu 12.04 ... Guess you will have to adapt it to whatever distro / version you are using.

@bradfeehan
Copy link

@bradfeehan bradfeehan commented Nov 12, 2013

I did say earlier this bug "annoys me unnaturally".. I decided today I wouldn't stop until I understood why this happens. 😄 Unfortunately this entire situation with shells and configuration files (.bashrc/.profile/etc). is really worse than I thought. It's obvious the current situation evolved "organically" and it really sucks to work with.

Vagrant defaults its SSH shell command to bash -l. This command is used for Vagrant's internal SSH communicator (which is used to execute commands in shell provisioners and plugins). The -l flag forces this to be a login shell. For a non-interactive login shell like this one, bash will source /etc/profile, followed by the first existing file out of ~/.bash_profile, ~/.bash_login, and ~/.profile. Since Vagrant runs most of its commands as root, it will source /etc/profile, then /root/.profile.

On Ubuntu, /root/.profile contains the command mesg n. This command is used to prevent other users on the machine writing to your current terminal device -- this is a good thing, it stops other users on the machine from writing to root terminals (I couldn't find much on the security implications, but a discussion of the potential reasons for this is available in [1, pp. 270]). However, this command doesn't even make sense when running commands as Vagrant does, because there is no terminal device at all (which is obvious, once you realise what mesg is for).

So it's true that Ubuntu's default /root/.profile doesn't check whether a terminal device is present before running mesg (as @mitchellh said initially), and that's why this problem is fixed when changing the relevant line to read tty -s && mesg -n as suggested by @andyshinn (it only runs mesg -n if tty reports that stdin is a terminal).

However, I don't think the onus is on Ubuntu to implement this change as @mitchellh suggests. Their /root/.profile assumes that all login shells are interactive -- but that's because they usually are. Login shells are usually started by the login process (or ssh when logging in interactively), and in those instances the shell would also be interactive. It's fairly unusual to have a login shell that's also non-interactive (the condition which triggers this problem).

A better way to fix this would be to avoid using a login shell. I think the only reason Vagrant chooses to use a login shell is so that /etc/profile is sourced before the command is run. On the base Ubuntu boxes provided by Vagrant, that executes /etc/profile.d/vagrantruby.sh, which adds /opt/ruby/bin into $PATH. So if you changed the Vagrant setting config.ssh.shell to bash (without the -l), it would fix this issue, but you would have to give the full path to Ruby because it wouldn't be in the $PATH. So I think to fix this problem "correctly", we need to find another way to get /opt/ruby/bin into the $PATH.

Honestly, I think there are some problems with the way the base box is built, specifically what happens in postinstall.sh. I'd open a pull request with some suggested changes, but I can't find that hosted anywhere official to do so. Here's my recommendations:

  1. Remove the trailing slash from the $PATH (currently /etc/profile.d/vagrantruby.sh contains PATH=$PATH:/opt/ruby/bin/, the trailing slash can cause problems, a trivial example being which ruby giving /opt/ruby/bin//ruby with two slashes).
  2. Actually export the change to $PATH (the current assignment to $PATH won't affect any sub-processes, which can be confusing)
  3. The main problem, however: we need to find another way to get /opt/ruby/bin into the $PATH. I really like the way OS X has /etc/paths.d (that would fix this problem awesomely) but unfortunately nothing like that is in Ubuntu yet. If you really really want to make extra double sure that Ruby is always available, why not chuck it into /etc/environment? This is sourced by login/sshd itself when logging in, no matter how you log in really.

tl;dr: Environment variables and shell configurations are FUBAR. @mitchellh (I believe?) should maybe adjust postinstall.sh used to build the official Vagrant Ubuntu base boxes -- don't use /etc/profile.d/vagrantruby.sh to add /opt/ruby/bin into the $PATH, let's modify /etc/environment instead. Citations. I have no life.

[1] B. Toxen, Real World Linux Security: Intrusion Prevention, Detection, and Recovery. Upper Saddle River, NJ: Prentice Hall, 2003. http://goo.gl/kmKryu

@bradfeehan
Copy link

@bradfeehan bradfeehan commented Nov 12, 2013

Oh, one more thing: for the time being, I'm fixing this by adding this line to my Vagrantfile:

config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"

This starts bash as a non-login shell, but also tells it to source /etc/profile, which I hypothesised to be the only reason to use a login shell by default. Works for me with the stock precise64 Vagrant box.

Some other ways to fix the issue:

  • Previous suggestions to change mesg n to tty -s && mesg n in /root/.profile
  • Remove the mesg n line from /root/.profile completely, if you don't care about the security/denial of service implications, or will only have trusted users on the virtual machine (passwordless sudo is enabled on the base boxes already anyway...)
  • Put a script named mesg in root's $PATH which only executes the real mesg if stdin is a tty (tested using tty -s or the preferred test -t 0)
  • Disable login shell for the SSH command in your Vagrantfile: config.ssh.shell = 'bash' -- you'll also have to use full paths to binaries in all of your provisioners, as ruby won't be found in $PATH (probably only feasible if only using shell provisioners)
@johnraz
Copy link

@johnraz johnraz commented Nov 12, 2013

@bradfeehan : Very interesting findings. Thanks for taking the time to dig this and share it with us.

@chrisabrams
Copy link

@chrisabrams chrisabrams commented Nov 19, 2013

@bradfeehan thank you so much for writing this up! I tried config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'" and it worked :)

sgviking added a commit to SocialGeeks/vagrant-openstack that referenced this issue Nov 26, 2013
… Vagrantfile. This supresses the harmless but annoying 'stdin: is not a tty' error that is generated every time a shell script provisioner is run.

Thanks @bradfeehan for your comment on this page: hashicorp/vagrant#1673
@gudmundur
Copy link

@gudmundur gudmundur commented Nov 27, 2013

@bradfeehan Wow, thanks! This bothered me to no end. I was about to go in for the deep dive to sort this out.

@phirschybar
Copy link

@phirschybar phirschybar commented Nov 28, 2013

@bradfeehan this worked for me! thanks.

@bradfeehan
Copy link

@bradfeehan bradfeehan commented Dec 9, 2013

There's a problem with this workaround that means you don't get ~/.bash_profile sourced when logging in interactively via vagrant ssh. I guess this problem really is so complex that there's no right answer.

I'm going to put up with the message, and solve it a different way when it annoys me too much again.

@allaire
Copy link

@allaire allaire commented Jan 20, 2014

If anybody get this error:

[2014-01-20T08:11:08-05:00] INFO: Chef Run complete in 67.290072613 seconds
[2014-01-20T08:11:08-05:00] INFO: Running report handlers
[2014-01-20T08:11:08-05:00] INFO: Report handlers complete
[2014-01-20T13:10:00+00:00] INFO: Forking chef instance to converge...
[2014-01-20T13:10:00+00:00] DEBUG: Fork successful. Waiting for new chef pid: 5680
[2014-01-20T08:11:08-05:00] DEBUG: Forked instance successfully reaped (pid: 5680)
[2014-01-20T08:11:08-05:00] DEBUG: Exiting

Or their vagrant box runs out of memory, remove the config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'" hack. For me, it was causing problem with the rbenv cookbook (https://github.com/RiotGames/rbenv-cookbook)

@Taytay
Copy link

@Taytay Taytay commented Feb 4, 2014

@phirschybar I was also getting that error message: " tty: extra operand 'mesg' "
It's because you have to double-escape the ampersands in @andyshinn's command. So the command would look like:

  config.vm.provision :shell,
    :inline => "sed -i 's/^mesg n$/tty -s \\&\\& mesg n/g' /root/.profile"

Note the double-backslashes before the ampersand. If you don't do that, you end up writing unintended text into /root/.profile, leading to that error message in subsequent provisions.

This command is almost perfect, but you still get that 'stdin is not a tty' on your very first provision. To reassure my colleagues when provisioning a box for the first time, I now add the following to my Vagrantfile:

#This next bit fixes the 'stdin is not a tty' error when shell provisioning Ubuntu boxes
  config.vm.provision :shell,
    #if there a line that only consists of 'mesg n' in /root/.profile, replace it with 'tty -s && mesg n'
    :inline => "(grep -q -E '^mesg n$' /root/.profile && sed -i 's/^mesg n$/tty -s \\&\\& mesg n/g' /root/.profile && echo 'Ignore the previous error about stdin not being a tty. Fixing it now...') || exit 0;"

That prints a reassuring green message right after the scary red 'stdin is not a tty' upon the very first provision.

(The only thing I don't like about it is that I used a redundant grep to determine if sed was going to do any work. You can use sed's 'q' command to determine if it did any work, but I'm already in over my Unix head, and couldn't get it to work.)

@Blaisorblade
Copy link

@Blaisorblade Blaisorblade commented Feb 8, 2014

I have the same problem, and for me it's an actual problem.

Why is there no option to have a TTY during provisioning?

The only answer I could imagine is "But provisioning should not be interactive". However, I always run provisioning on a terminal and watch the output.

There exist commands which require a TTY, even when they do not actually need to interact with the user — in my case, it was "agda-mode setup" from Agda starting Emacs, mostly just to find it (I'm sure you didn't hear of Agda).

Debian package installation also requires a TTY, though that's actually interactive; however, upon finding no TTY, in my setup it still tries to use ncurses and ends up corrupting the terminal settings, requiring to run reset in the host terminal.

I'm working this around by provisioning with vagrant ssh -c /vagrant/myscript.sh, but that seems to half-defeat the point of having provisioning.

@mitchellh
Copy link
Member

@mitchellh mitchellh commented Feb 8, 2014

@Blaisorblade There is: config.ssh.pty = true (min Vagrant 1.4.0)

@Blaisorblade
Copy link

@Blaisorblade Blaisorblade commented Feb 8, 2014

Thanks! But shouldn't it be documented under both of
http://docs.vagrantup.com/v2/vagrantfile/ssh_settings.html
http://docs.vagrantup.com/v2/provisioning/shell.html
(so that one can find it from both places), while it isn't documented in either page?

Also, while this setting solves my problem, provisioning does not terminate if I actually use "agda-mode setup", which does use the terminal in strange ways. It's still better, but not perfect. (Also, the same script works fine inside ssh — and enabling keep_color does not help).

@Blaisorblade
Copy link

@Blaisorblade Blaisorblade commented Feb 9, 2014

In addition, with config.ssh.pty the default shared folder is mounted under logout (meaning /home/vagrant/logout) instead of /vagrant. I guess some command is happy to see a TTY and is producing output which Vagrant doesn't expect, but usually login/logout scripts are supposed to not produce output with non-interactive shells.

I also tried adding :binary => true to the provisioning configuration, but it didn't help.

@gidantribal
Copy link

@gidantribal gidantribal commented Apr 18, 2016

I didn't understand, how is this closed if I have still the same issue? Is the workaround a kind configuration? Is there documentation?

@gidantribal
Copy link

@gidantribal gidantribal commented Apr 18, 2016

ubuntu 14.10 as guest,
windows 10 as host
vagrant 1.8.1
vb-guest 0.11.1

The workaround of @johnraz works:

config.vm.provision "fix-no-tty", type: "shell" do |s|
    s.privileged = false
    s.inline = "sudo sed -i '/tty/!s/mesg n/tty -s \\&\\& mesg n/' /root/.profile"
end
@liquidice
Copy link

@liquidice liquidice commented Aug 7, 2016

I'm getting the issue on:

Vagrant 1.8.5
VirtualBox 5.0.26
bento/ubuntu-16.04 version 20160805.0.0

default: Running: /var/folders/fv/4bgskv153wz93tdmbvmfb9fh0000gn/T/vagrant-shell20160807-7353-126ogg7.sh ==> default: mesg: ==> default: ttyname failed ==> default: : ==> default: Inappropriate ioctl for device

I re-wrote the /root/.profile editing snippet because it was broken for me:

(grep -q -E '^(mesg n \|\| true)$' /root/.profile && sed -ri 's/^(mesg n \|\| true)$/tty -s \&\& mesg n/' /root/.profile && echo 'Ignore the previous error about stdin not being a tty. Fixing it now...')

The error only occurs once while provisioning now.

@Ajedi32
Copy link

@Ajedi32 Ajedi32 commented Aug 10, 2016

@liquidice That's probably a different issue. See #7155

@liquidice
Copy link

@liquidice liquidice commented Aug 10, 2016

@Ajedi32 As I said, I run that code I provided above on initial provision, and the problem only happens once on initial provision now, instead of every time.

@behrangsa
Copy link

@behrangsa behrangsa commented Sep 11, 2016

This is happening for me as well. I have attached the log file: vagrant.log.tar.gz.

Here are the annoying messages that appear when I run vagrant up:

$ vagrant up
.
.
.
==> acs: mesg:
==> acs: ttyname failed
==> acs: :
==> acs: Inappropriate ioctl for device
.
.
.
==> acs: dpkg-preconfigure: unable to re-open stdin: No such file or directory

Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  # ansible control center
  config.vm.define "acs" do |acs|
    acs.vm.box = "boxcutter/ubuntu1604"
    acs.vm.hostname = "acs"
    acs.vm.network "private_network", ip: "192.168.33.10"
    acs.vm.provision "shell", inline: "sed -i 's/us.archive.ubuntu/au.archive.ubuntu/g' /etc/apt/sources.list && apt-get update && apt-get install ansible -y"
  end

end

Host OS: Ubuntu 16.04
VirtualBox version: 5.0.24_Ubuntur108355


CC: @mitchellh

@lshw
Copy link

@lshw lshw commented Nov 4, 2016

mount -t devtmpfs none /home/chroot/dev
mount -t devpts none /home/chroot/dev/pts

@berdon
Copy link

@berdon berdon commented Nov 14, 2016

I'm running into an issue with apt-get update if I use the fix-no-tty solution. Essentially, apt-get just stalls and does nothing.

Edit: It might just be apt-get hanging...

@Blaisorblade
Copy link

@Blaisorblade Blaisorblade commented Nov 15, 2016

@berdon You sure apt-get isn't waiting for console input? Then it might do different things on a terminal or not (even failing on a non-terminal). That's surprising for apt-get update, but if a program isn't using input at all it shouldn't notice...

@berdon
Copy link

@berdon berdon commented Nov 16, 2016

@Blaisorblade

I believe the issue was unrelated to Vagrant and more likely related to IPv6 issues and apt-get. I ran across a StackExchange post suggesting disabling IPv6 for updates and upgrades. This seems to have fixed the issue:

Pre-Config shell script:

echo "Disabling IPv6"
sudo cp /etc/sysctl.conf /etc/sysctl.conf.bak
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >>  /etc/sysctl.conf
echo "net.ipv6.conf.lo.disable_ipv6 = 1" >>  /etc/sysctl.conf
sudo sysctl -p

Post-Config shell script:

# sudo apt-get -qq -y update
echo "Resetting IPv6"
mv /etc/sysctl.conf.bak /etc/sysctl.conf
rcmoutinho pushed a commit to toolscloud/deploy-toolscloud that referenced this issue Jan 22, 2019
Little hack on Vagrant file to remove "is not a tty" messages according to:
hashicorp/vagrant#1673
@ghost
Copy link

@ghost ghost commented Apr 3, 2020

I'm going to lock this issue because it has been closed for 30 days . This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@hashicorp hashicorp locked and limited conversation to collaborators Apr 3, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet