heroku / legacy-cli

Heroku CLI
https://cli.heroku.com
MIT License
1.37k stars 380 forks source link

heroku run hangs when stdin is piped in #1409

Open jdx opened 9 years ago

jdx commented 9 years ago

as explained in https://github.com/heroku/heroku/pull/811 commands like this

$ echo ls | heroku run bash

will work, but it is noninteractive and ends up locking you inside bash. There is a workaround:

echo ls | heroku run bash --noediting

but hopefully there is a way for the CLI to make this unnecessary.

drewB commented 8 years ago

How would you actually use this workaround? I am trying to pipe in a file to a rake task. I have tried the following and they are all hang expecting stdin.

cat file.csv | heroku run bash --noediting -c "rake my_rake_task"
cat file.csv | heroku run bash -c "rake my_rake_task"
heroku run bash --noediting -c "rake my_rake_task" < file.csv
heroku run bash -c "rake my_rake_task" < file.csv
jdx commented 8 years ago

what do you have for heroku version? I'm not able to reproduce.

drewB commented 8 years ago

heroku-toolbelt/3.42.22 (x86_64-darwin10.8.0) ruby/1.9.3 heroku-cli/4.27.7-135a760 (amd64-darwin) go1.5.1 === Installed Plugins heroku-apps@0.5.4 heroku-cli-addons@0.1.1 heroku-fork@4.0.0 heroku-git@2.4.3 heroku-local@4.1.5 heroku-run@2.9.2 heroku-status@1.2.3

pre commented 8 years ago

I have this same problem.:) I'm also trying to feed seed data to Rake from STDIN.

Command: cat FILENAME | heroku run bash --noediting -c "rake db:seed:TASKNAME"

Three notes:

1) If FILENAME has only a small amount of lines, reading from STDIN will always succeed, rake will receive EOF as expected and the process will stop eventually.

2) If FILENAME has 900 lines of plain text (56kB), reading from STDIN line-by-line STDIN.each do |line| will succeed, but rake will not receive EOF and the process will not stop.

3) If FILENAME has 900 lines of plaintext (56kB), reading from STDIN all-at-once lines = STDIN.read will echo contents on the screen, but rake will not receive EOF and will not process lines. Process will not stop.

heroku-toolbelt/3.43.9 (x86_64-darwin15) ruby/2.3.1
heroku-cli/5.2.39-010a227 (darwin-amd64) go1.6.2
=== Installed Plugins
heroku-certs@1.1.14

Example Rake task:

namespace :seed do
  task :all_at_once do    
    lines = STDIN.read
    puts "Got lines:"
    puts lines
  end

  task :line_by_line do
    STDIN.each do |line|
      puts "Got line:"
      puts line
    end
  end
end
pre commented 8 years ago

Related:

ransombriggs commented 8 years ago

@pre Could you try running the following?

cat FILENAME | heroku run --no-tty rake db:seed:TASKNAME

The heroku run command by default runs in a terminal, adding the --no-tty will force it to not run in a tty. The reason it hangs in a tty is due to some buffering issues that we found that users were hitting around 4k of input. I wanted to automatically enable this flag, but we cannot reliably detect a tty on all platforms (specifically cygwin on Windows)

pre commented 8 years ago

You know what, it works with --no-tty! Thanks @ransombriggs!

Yesterday I settled to a workaround where the Rake task reads from STDIN and I copypaste the data into the terminal. But this is better. :)

Both of the following commands work for both reading stdin all-at-once and line-by-line:

albertnetymk commented 8 years ago

--no-tty works for me as well. Thank @ransombriggs very much.