3

I have several shell scripts (bash) which are started by cron. Every time a script is executed I get an email saying "stdin: is not a tty". Can someone please tell me how to fix this? All scripts run successfully but these mails are killing my email folder.

I use Debian Wheezy. "/root/.bashrc" is empty. Cron entries are like:

/bin/bash --login /root/script.sh > /dev/null

Even this script produces the error message:

#!/bin/bash
ls

Content of .profile:

# ~/.profile: executed by Bourne-compatible login shells.

if [ "$BASH" ]; then
  if [ -f ~/.bashrc ]; then
    . ~/.bashrc
  fi
fi

mesg n
  • It's something in your script (or in your .profile or .bash_profile since you're telling bash to read it). We can't help you unless you post the script content. If you want to diagnose what it might be, add set -x at the top of the script. – Gilles Jan 16 '14 at 0:45
  • @Gilles: Thx. The scripts are quite long but even calling 'ls' produces the error. – user4811 Jan 16 '14 at 1:03
  • stty and mesg are the typical culprits. You can run them with a 2>/dev/null to quiet them. – Mark Plotnick Jan 16 '14 at 1:07
  • @MarkPlotnick: I have commented 'mesg n' out (whatever is does) and it works but this doesn't seems to be the right solution. If I write '2>/dev/null' instead of '>/dev/null' I don't get the "stdin:..." error message but instead the output of the ls command which I also don't want. – user4811 Jan 16 '14 at 1:16
  • Sorry, I meant to say to put 2>/dev/null just on the line that does the mesg. – Mark Plotnick Jan 16 '14 at 1:22
3

Something in your .bashrc is assuming that the shell is running on a terminal. That's perfectly fine: .bashrc is supposed to run only in interactive shells, and interactive shells are supposed to run only on terminals.

The problem is that you're systematically including .bashrc from .profile. That's wrong: you should only include .bashrc in interactive shells.

Change your .profile to

# Bash doesn't load its interactive initialization file if it's invoked as
# a login shell, so do it manually.
case $- in
  *i*) if [ -n "$BASH" ]; then . ~/.bashrc;; fi
esac

Move mesg n into .bashrc: it's a terminal-related command, not a session-related command.

If you have environment variable definitions in your .bashrc, move them to .profile. The .profile file is for things that are executed when your session starts, typically mainly environment variable definitions, used by any application that you'll run during the session. The .bashrc file is the configuration file for bash when running interactively, it typically contains terminal setup, alias definitions, shell options and completion settings, and other things related to the interactive use of the shell.

For background, see:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.