{"action":"created","issue":{"url":"https://api.github.com/repos/shelljs/shelljs/issues/277","labels_url":"https://api.github.com/repos/shelljs/shelljs/issues/277/labels{/name}","comments_url":"https://api.github.com/repos/shelljs/shelljs/issues/277/comments","events_url":"https://api.github.com/repos/shelljs/shelljs/issues/277/events","html_url":"https://github.com/shelljs/shelljs/issues/277","id":125744819,"number":277,"title":"Ability to read the stdout buffer line-by-line","user":{"login":"nathanbrauer","id":323945,"avatar_url":"https://avatars.githubusercontent.com/u/323945?v=3","gravatar_id":"","url":"https://api.github.com/users/nathanbrauer","html_url":"https://github.com/nathanbrauer","followers_url":"https://api.github.com/users/nathanbrauer/followers","following_url":"https://api.github.com/users/nathanbrauer/following{/other_user}","gists_url":"https://api.github.com/users/nathanbrauer/gists{/gist_id}","starred_url":"https://api.github.com/users/nathanbrauer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nathanbrauer/subscriptions","organizations_url":"https://api.github.com/users/nathanbrauer/orgs","repos_url":"https://api.github.com/users/nathanbrauer/repos","events_url":"https://api.github.com/users/nathanbrauer/events{/privacy}","received_events_url":"https://api.github.com/users/nathanbrauer/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/shelljs/shelljs/labels/feat","name":"feat","color":"84b6eb"},{"url":"https://api.github.com/repos/shelljs/shelljs/labels/low%20priority","name":"low priority","color":"aaaaaa"}],"state":"open","locked":false,"assignee":{"login":"nfischer","id":5801521,"avatar_url":"https://avatars.githubusercontent.com/u/5801521?v=3","gravatar_id":"","url":"https://api.github.com/users/nfischer","html_url":"https://github.com/nfischer","followers_url":"https://api.github.com/users/nfischer/followers","following_url":"https://api.github.com/users/nfischer/following{/other_user}","gists_url":"https://api.github.com/users/nfischer/gists{/gist_id}","starred_url":"https://api.github.com/users/nfischer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nfischer/subscriptions","organizations_url":"https://api.github.com/users/nfischer/orgs","repos_url":"https://api.github.com/users/nfischer/repos","events_url":"https://api.github.com/users/nfischer/events{/privacy}","received_events_url":"https://api.github.com/users/nfischer/received_events","type":"User","site_admin":false},"milestone":null,"comments":2,"created_at":"2016-01-09T07:47:03Z","updated_at":"2016-01-15T05:17:17Z","closed_at":null,"body":"For example, with `exec('...', { silent: false });` within a `gulp` stream, you'll get this:\r\n```bash\r\nnathanbrauer@macthan:~/Web/git/Component-Core$ gulp compile:styles\r\n[18:33:08] Using gulpfile ~/Web/git/Component-Core/gulpfile.js\r\n[18:33:08] Starting 'compile:styles'...\r\n    write build/brand.css (0.713s)\r\n\r\n    write build/brand.css.map\r\n\r\n[18:33:10] Finished 'compile:styles' after 1.17 s\r\n```\r\n\r\nIdeally, each of the lines (starting with `write build/brand.css...`) would also conform to gulp's logging (`gutils.log(...)`).  But the only way to do that, currently, is to wait for the entire buffer to end, then parse every line on your own.  *This means that the timestamps are completely wrong which makes it pointless...* (but at least it's prettier :wink:):\r\n\r\n```js\r\nvar output = exec('...', { silent: true }).output,\r\n\toutput_lines = output.replace(/^\\s+|\\s+$/,'').split(/[\\n\\r]+/),// Trims the output and returns it split into an array of lines\r\n\tlog_line;\r\nif (output) {\r\n\tfor (log_line = 0; log_line < output_lines.length; ++log_line) {\r\n\t\tgutil.log(log_indent,output_lines[log_line]);\r\n\t}\r\n}\r\n```\r\n\r\nHere's a real example: https://github.com/Marketera/gulp-composer/blob/master/index.js#L28\r\n\r\nIdeally we'd be able to do something along the lines of....\r\n\r\n```js\r\nvar cmd = exec('composer install', {\r\n    silent: true,\r\n    onPrint: function(line){\r\n        gutil.log(line);\r\n    }\r\n});\r\n\r\n// ...which is basically the same as:\r\nvar cmd = exec('composer install', {\r\n    silent: true,\r\n    onPrint: gutil.log\r\n});\r\n\r\n// ...the default behavior, essentially being:\r\nvar cmd = exec('composer install', {\r\n    //...\r\n    onPrint: console.log\r\n});\r\n```\r\n\r\nSome kind of way to \"`CTRL+C`\" should also be included...\r\n```js\r\nvar cmd = exec('composer install', {\r\n    silent: true,\r\n    onPrint: function(line){\r\n        if (is_something_bad(line)) {\r\n          stream.emit('error', new gutil.PluginError('exec', \"I didn't like this line: \" + line));\r\n        }\r\n        gutil.log(line);\r\n    }\r\n});\r\n```"},"comment":{"url":"https://api.github.com/repos/shelljs/shelljs/issues/comments/171873868","html_url":"https://github.com/shelljs/shelljs/issues/277#issuecomment-171873868","issue_url":"https://api.github.com/repos/shelljs/shelljs/issues/277","id":171873868,"user":{"login":"nfischer","id":5801521,"avatar_url":"https://avatars.githubusercontent.com/u/5801521?v=3","gravatar_id":"","url":"https://api.github.com/users/nfischer","html_url":"https://github.com/nfischer","followers_url":"https://api.github.com/users/nfischer/followers","following_url":"https://api.github.com/users/nfischer/following{/other_user}","gists_url":"https://api.github.com/users/nfischer/gists{/gist_id}","starred_url":"https://api.github.com/users/nfischer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nfischer/subscriptions","organizations_url":"https://api.github.com/users/nfischer/orgs","repos_url":"https://api.github.com/users/nfischer/repos","events_url":"https://api.github.com/users/nfischer/events{/privacy}","received_events_url":"https://api.github.com/users/nfischer/received_events","type":"User","site_admin":false},"created_at":"2016-01-15T05:17:17Z","updated_at":"2016-01-15T05:17:17Z","body":"@nathanbrauer @tminglei\r\n\r\nWould this section of [the docs](https://github.com/shelljs/shelljs#execcommand--options--callback) help you do what you want to achieve? It looks like you can get the results in real-time, chunk by chunk. Then it's just up to you to parse for a newline (or whatever you need) and do something with the line of text."}}