# 外部コマンド実行. 標準出力を取得

# Bash

AAA=`ls -l`
AAA=$( ls -l )

$( .. ) の方は bash でしか使えないが、入れ子できて便利

# C++

system()
// 外部コマンド実行したいだけのときには使わないのがいい
// 中で fork() するのでメモリを浪費する+時間がかかる?

# PHP

$lastLine = exec($cmd, $out, $retcode);
# $lastLine = 最後の行
# $out は配列。標準出力のみ

他に

system($cmd);
passthrough()
$ret = `$cmd1`;
  • system <=> exec の違いは、コマンドの実行結果が画面表示されるかどうかの違い?

それぞれのコマンド実行結果受け取り方

戻り値 第2引数 標準出力
system .
passthru .
exec . .

# Python

p = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = p.communicate()
r = p.returncode # 正常 = 0
  • この方式だと stdout, stderr, returncode が別々で取れるのが良い気がする。

下記もある?

subprocess.getoutput('ls -l')
  • subprocess.call() とかは エラー時は例外なので注意。 subprocess.Popen では発生しない
import os
os.system('ls -l')
# 標準出力にはコマンドの標準出力が出る
# 戻り値には、コマンドの戻り値が入る。

import commands
commands.getoutput('ls -l')
# 標準出力には何も出ない
# 戻り値には、コマンドの標準出力が入る。
# これは 2.6 あたりから deprecated なので使わない

# Ruby

`command1`
Kernel.system('command1')
Open3.capture3('command1')
(str_out, str_err, str_status) = Open3.capture3("pygmentize -f html -P 'tabsize=4' -P 'linenos=1' -l #{tag}", :stdin_data => str_in)
IO.popen('/xx/xx/command', 'r+') do |io|
  io.puts "xxxxxxxxxx"
  result = io.gets
end

(1) 呼び出して、決まった文字列が来たら落とす

require 'thread'

q = Queue.new

# 別スレッドでコマンド実行
t_command = Thread::new {
    IO.popen('コマンド名 引数1 ..') {|io|
        while (line = io.gets)
            q.push(line)
        end
    }
}
t_command.run

# 受け取る
while (line = q.pop)
    if (line ~= /end_end_end/)
        t_command.kill
        break
    end

    puts " --- #{line}"
end

(2) 呼び出して、決まった時間経ったら落とす

require 'thread'

lines = Array.new

# 別スレッドでコマンド実行
t_command = Thread::new {
    IO.popen('コマンド名 引数1 ..') {|io|
        while (line = io.gets)
            lines.push(line)
        end
    }
}
t_command.run

# タイマー
t_timer = Thread::new {
    Thread.stop
    sleep 5
    t_command.kill
}
t_timer.run
t_timer.join

# 受け取る
puts lines

[ 📩 ご意見 ]