Can Ruby Tell If It Is Called from an Interactive Shell or Cron

Can ruby tell if it is called from an interactive shell or cron?

$stdout.tty? returns true if $stdout is associated with a terminal device (i.e. an interactive user) and false otherwise:

# test.rb
if $stdout.tty?
puts "tty"
else
puts "not a tty"
end

From bash:

$ ruby test.rb
tty

$ ruby test.rb > test.log
$ cat test.log
not a tty

How can a Ruby script detect if it was triggered by an interactive shell?

Check if STDIN is a "TTY" (literally meaning teletypewriter) with IO#isatty.

$ ruby -e 'puts STDIN.isatty'
true
$ echo "no" | ruby -e 'puts STDIN.isatty'
false

How can I determine if my process is being run interactively?

I've always used $stdout.isatty to check for this. Other approaches might include checking the value of ENV['TERM'] or utilizing the ruby-terminfo gem.

How can I tell if a makefile is being run from an interactive shell?

It isn't strictly determining whether it is invoked from an interactive shell or not, but for a cron job in which the output is redirected to a file, the answer to this question would be the same as for How to detect if my shell script is running through a pipe?:

if [ -t 0 ]
then
# input is from a terminal
fi

Edit: To use this to set a variable in a Makefile (in GNU make, that is):

INTERACTIVE:=$(shell [ -t 0 ] && echo 1)

ifdef INTERACTIVE
# is a terminal
else
# cron job
endif

why bash -l -c CMD makes ruby find my gem?

The -l parameter executes the command in a login shell, which means that it inherits your path and other settings from your shell profile. The cron job, if run without the login shell, will be run without any path environment variables set (such as those set by RVM), which results in the system being unable to find the referenced gems.

Ruby script extracts wrong value when executed with crontab

That could be an environment problem, which could include bad paths, etc. You can compare your ENV from the command-line to the environment when launched by crontab.

Try:

ruby -rpp -e 'pp ENV' > /tmp/crontab_env.out

from crontab, then:

ruby -rpp -e 'pp ENV' > /tmp/cmd_env.out

from the command-line, then:

vimdiff /tmp/*env.out

or use a regular editor.

ruby script cron not working

This has nothing to do with cron, actually. ~ is a feature of the shell, Ruby doesn't know what it is. Only some methods in Ruby deal with ~, e.g. File::expand_path. So, Ruby is literally trying to open a file named newfile.txt in directory named ~ in the current working directory. Try it out yourself: create an empty directory named ~ in your home directory, and sure enough, after 1 minute, you should find a new file named newfile.txt with the content hi.. in there.

There are a couple of ways to fix this, I will leave it up to you which one to use:

File.open(File.expand_path('~/newfile.txt'), 'a') do |f| end
File.open(File.join(Dir.home, 'newfile.txt'), 'a') do |f| end

[Note: if you only want to append to the end of the file, not move around or read, a is enough, you don't need a+.]

See the documentation for File::expand_path (bold emphasis mine):

expand_path(file_name [, dir_string] )abs_file_name

Converts a pathname to an absolute pathname. Relative paths are referenced from the current working directory of the process unless dir_string is given, in which case it will be used as the starting point. The given pathname may start with a “~”, which expands to the process owner’s home directory (the environment variable HOME must be set correctly). “~user” expands to the named user’s home directory.



Related Topics



Leave a reply



Submit