I have this ruby script that I use quite often:
$stdin.each_line do |it|
it.strip!
eval(ARGV.first)
end
For instance:
> dir | each "Dir.chdir(it) { puts it; system('bundle') }"
code
Bundle complete! 41 Gemfile dependencies, 165 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
code-ruby
Bundle complete! 6 Gemfile dependencies, 44 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
I do this "puts it" quite often and would rather have my output be prepended by the "it".
e.g.
> dir | each "Dir.chdir(it) { system('bundle') }"
[code] Bundle complete! 41 Gemfile dependencies, 165 gems now installed.
[code] Use `bundle info [gemname]` to see where a bundled gem is installed.
[code-ruby] Bundle complete! 6 Gemfile dependencies, 44 gems now installed.
[code-ruby] Use `bundle info [gemname]` to see where a bundled gem is installed.
This is even more obvious with the parallel version:
Parallel.each($stdin.each_line.to_a) do |it|
it.strip!
eval(ARGV.first)
end
You can override system
output and add prefix for every line of output:
def system(cmd)
rd, wr = IO.pipe
Thread.new do
Kernel.system(cmd, out: wr)
wr.close
end
until rd.eof?
line = rd.gets
puts "[#{Thread.current[:prefix]}] #{line}"
end
rd.close
end
$stdin.each_line do |it|
Thread.current[:prefix] = it.strip!
eval(ARGV.first)
end
Test:
$ ls | ./each "Dir.chdir(it) { system('bundle') }"
[app1] Fetching gem metadata from https://rubygems.org/..........
[app1] Resolving dependencies...
[app1] Fetching minitest 5.25.1
[app1] Fetching parallel 1.26.3
[app1] Fetching brakeman 6.2.1
[app1] Fetching rexml 3.3.6
[app1] Installing parallel 1.26.3
...
[app1] Fetching stimulus-rails 1.3.4
[app1] Installing rails 7.2.1
[app1] Installing stimulus-rails 1.3.4
[app1] Bundle complete! 16 Gemfile dependencies, 99 gems now installed.
[app1] Use `bundle info [gemname]` to see where a bundled gem is installed.
[app2] Fetching gem metadata from https://rubygems.org/..........
[app2] Resolving dependencies...
[app2] Bundle complete! 16 Gemfile dependencies, 99 gems now installed.
[app2] Use `bundle info [gemname]` to see where a bundled gem is installed.
[app3] Fetching gem metadata from https://rubygems.org/..........
[app3] Resolving dependencies...
[app3] Bundle complete! 16 Gemfile dependencies, 99 gems now installed.
[app3] Use `bundle info [gemname]` to see where a bundled gem is installed.
Update
You could run a separate process, like foreman
does for each command, this way all output is redirected, and seems to work with parallel
:
require "parallel"
Parallel.each($stdin.each_line.to_a) do |it|
prefix = it.strip!
rd, wr = IO.pipe
pid = Process.spawn(RbConfig.ruby, "-e", %(it="#{it}"), "-e", ARGV.first, out: wr, err: wr)
wr.close
loop do
if rd.eof?
puts "[#{prefix}] process #{pid} closed"
break
else
line = rd.gets
puts "[#{prefix}] #{line}"
end
end
end
$ ls | ./each "Dir.chdir(it) { system('bundle'); puts 'hi' }"
[app2] Bundle complete! 16 Gemfile dependencies, 99 gems now installed.
[app2] Use `bundle info [gemname]` to see where a bundled gem is installed.
[app2] hi
[app2] process 1808150 closed
[app3] Bundle complete! 16 Gemfile dependencies, 99 gems now installed.
[app3] Use `bundle info [gemname]` to see where a bundled gem is installed.
[app3] hi
[app3] process 1808151 closed
[app1] Bundle complete! 16 Gemfile dependencies, 99 gems now installed.
[app1] Use `bundle info [gemname]` to see where a bundled gem is installed.
[app1] hi
[app1] process 1808149 closed