How to execute shell script from hubot - linux

I got my first hubot up and running, and wrote my first few scripts based on the existing examples. My existing workflow, which I would like to integrate with hubot, is essentially based on several shell scripts, each one of them performing one task. The task can be relatively complex (git/svn checkout, compiling code with gcc, and running it). How can I execute a bash script with hubot? I have seen this question, but it only addresses simple commands such as ls. I tried
build = spawn 'source', ['test.sh']
build.stdout.on 'data', (data) -> msg.send data.toString()
build.stderr.on 'data', (data) -> msg.send data.toString()
without any luck:
Hubot> execvp(): Permission denied
I checked the obvious things (-rwxr-xr-x permissions), and export HUBOT_LOG_LEVEL="debug".
I am running hubot with the same user that owns the bash scripts.
Thanks.

For reference: the answer was
build = spawn '/bin/bash', ['test.sh']
Dah

npm install hubot-script-shellcmd
is your doorway to the shell.

Related

Terminal in React-Electron app

My requirement is to embed a terminal in my React-Electron app wherein all commands which I can run from bash can be run in the embedded terminal too.
Suppose I want to 'npm install' I want it to be possible through my embedded terminal too. Could anyone suggest possible solutions ?
I'm not exactly sure, but I bet you can create a interface with an text input, get the content from it, and use some function of NodeJS to run that content (witch should be a command). Then, just print the result on the screen.
You can use the exec function from "child_process" dependencie, like this.
const { exec } = require("child_process");
exec("ls");
For more details, you can check here: https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback

Environment variables not getting created by Chef

I am trying to create some new env variables in the rhel machine using chef.
The block executes successfully but on trying to echo the value, i am getting black result.
Script-1:
execute 'JAVA_HOME' do
command 'export JAVA_HOME='+node['java']['home']
end
Script-2:
bash 'env_test' do
code <<-EOF
echo $chef
EOF
environment ({ 'chef' => 'chef' })
end
Also gave this a shot as it was mentioned in the documentation:
ENV['LIBRARY_PATH'] = node['my']['lib']
Please let me know where am i going wrong here..
So the thing you need to know about environment variables is they only work in one direction (parent process to children) so an export in a subcommand does nothing after that execute resource finishes. The second and third examples both work though, with the second setting it for just that bash resource and the third for both the Chef process and everything it spawns. Remember that you need to run with with -l debug to see the output from subcommands Chef runs.
Above explanation is pretty helpful. Updating the /etc/environments file using chef to make sure that env variables are present from the next session. Also using the 3rd approach to make the env variables available for the current session.

How to run two shell scripts at startup?

I am working with Ubuntu 16.04 and I have two shell scripts:
run_roscore.sh : This one fires up a roscore in one terminal.
run_detection_node.sh : This one starts an object detection node in another terminal and should start up once run_roscore.sh has initialized the roscore.
I need both the scripts to execute as soon as the system boots up.
I made both scripts executable and then added the following command to cron:
#reboot /path/to/run_roscore.sh; /path/to/run_detection_node.sh, but it is not running.
I have also tried adding both scripts to the Startup Applications using this command for roscore: sh /path/to/run_roscore.sh and following command for detection node: sh /path/to/run_detection_node.sh. And it still does not work.
How do I get these scripts to run?
EDIT: I used the following command to see the system log for the CRON process: grep CRON /var/log/syslog and got the following output:
CRON[570]: (CRON) info (No MTA installed, discarding output).
So I installed MTA and then systemlog shows:
CRON[597]: (nvidia) CMD (/path/to/run_roscore.sh; /path/to/run_detection_node.sh)
I am still not able to see the output (which is supposed to be a camera stream with detections, as I see it when I run the scripts directly in a terminal). How should I proceed?
Since I got this working eventually, I am gonna answer my own question here.
I did the following steps to get the script running from startup:
Changed the type of the script from shell to bash (extension .bash).
Changed the shebang statement to be #!/bin/bash.
In Startup Applications, give the command bash path/to/script to run the script.
Basically when I changed the shell type from sh to bash, the script starts running as soon as the system boots up.
Note, in case this helps someone: My intention to have run_roscore.bash as a separate script was to run roscore as a background process. One can run it directly from a single script (which is also running the detection node) by having roscore& as a command before the rosnode starts. This command will fire up the master as a background process and leave the same terminal open for following commands to be executed.
If you could install immortal you could use the require option to start in sequence your services, for example, this is could be the run config for /etc/immortal/script1.yml:
cmd: /path/to/script1
log:
file: /var/log/script1.log
wait: 1
require:
- script2
And for /etc/immortal/script2.yml
cmd: /path/to/script2
log:
file: /var/log/script2.log
What this will do it will try to start both scripts on boot time, the first one script1 will wait 1 second before starting and also wait for script2 to be up and running, see more about the wait and require option here: https://immortal.run/post/immortal/
Based on your operating system you will need to configure/setup immortaldir, her is how to do it for Linux: https://immortal.run/post/how-to-install/
Going more deep in the topic of supervisors there are more alternatives here you could find some: https://en.wikipedia.org/wiki/Process_supervision
If you want to make sure that "Roscore" (whatever it is) gets started when your Ubuntu starts up then you should start it as a service (not via cron).
See this question/answer.

SSH - npm seems to break ssh non-pty shells

I am developing a library/tool which lets the user execute arbitrary commands via SSH. Overall, this lib/tool will serve as software deployment tool, which needs access to remote machines to execute several commands (cd, mkdir, git ..., npm install, scp, etc).
While it basically works to execute remote commands via SSH, it seems that every time the command npm install is executed, the SSH connection gets terminated. I cannot tell what is causing this, but this very simple Node.js script can demonstrate it:
const spawn = require('child_process').spawn;
const bat = spawn('ssh', ['-T', '-oRequestTTY=no', '-oBatchMode=yes', 'user#host']);
bat.stdout.on('data', (data) => console.log('STDOUT: ' + data.toString()));
bat.stderr.on('data', (data) => console.log('STDERR: ' + data.toString()));
bat.on('exit', (code) => console.log(`Child exited with code ${code}`));
setTimeout(() => {
bat.stdin.write('pwd -P\n');
bat.stdin.write('cd someDir\n');
bat.stdin.write('npm install\n');
setTimeout(() => bat.stdin.write('pwd -P\n'), 2000);
}, 2000);
This will break/terminate the forked SSH process after npm install, so the delayed pwd -P will also fail. Removing the npm install command will make the SSH process stay intact until the app is terminated by the user.
I have actually faced this problem when I was working with the c library libssh, which had the very same issue, although I failed to notice that the npm install command seems to actually trigger the problem. See this related post: Channel in libssh gets closed for no obvious reason
What I found out is:
1. I am using a non-pty SSH shell
2. The libsshpacket-level debug output shows a packet 98 sent by the server just before the connection is closed
3. According to the RFC, packet 98 is SSH_MSG_CHANNEL_REQUEST, which can also be used to request a pty
So my asumption is, that I am working on a non-pty shell over SSH, and that something in the npm programm directly or indirectly leads to a server-side request for a pty, which cannot be handled by the non-pty shell I am working on, and thus, the SSH connection is closed on protocol-level.
Now my question is, what could be causing this, and is there a way to get rid of this problem?
Update may 29th
Actually, I was able to investigate this issue further. I started editing npm-cli.js and commented out everything, then step-by-step uncommented the lines, to see what is going to trigger the above behaviour.
At first, it seemed like the set-blocking module included via npmlog was causing the issue, but after also commenting out the actual code of set-blocking in index.js:4 (which is only stream._handle.setBlocking(blocking)), the bad behaviour still occurs, which confused the fuck out of me. Experimenting further revealed that actually the single piece of process.stdout is causing the whole issue.
To verify, I did the following:
Comment-out lines 22-94 in npm-cli.js. Executing npm install now will essentially do nothing. Also, running my example program above will not have the error.
Add the following code to npm-cli.js:19: if (process.stdout) ;. This also essentially does nothing, but it leads to the error occur again if executing the above test program.
Do the opposite test and change if (process.stdout) ; to if (process) ; - the test program will now run again without error.
So basically the above Node.js testprogram which demonstrates the error can be changed so that instead of npm install a simple oneline script is invoked, which results in the same error:
const spawn = require('child_process').spawn;
const bat = spawn('ssh', ['user#host']);
setTimeout(() => {
bat.stdin.write('node test.js\n'); // this breaks it
setTimeout(() => bat.stdin.write('pwd -P\n'), 2000);
}, 2000);
With test.js containing:
if (process.stdout) ; // only this line
I dont know how the process global object is constructed, or what is going on here, but something in Node.js' process/process.stdout object is somehow breaking SSH connections. I therefore think this is not an actual issue of npm, only indirectly.
Could anyone help to clarify?

“bash read command” in nodejs

I wanna write a git hook scripts with nodejs which I'm good at. In bash files, I can get params like this:
#!/bin/bash
read local_ref local_sha remote_ref remote_sha
Is there any same command in nodejs?
#!/usr/bin/env node
"bash read function in nodejs"
here are some module which help u to write command
node-cmd
Simple commandline/terminal interface to allow you to run cli or bash style commands as if you were in the terminal.
shelljs
ShellJS is a portable (Windows/Linux/OS X) implementation of Unix shell commands on top of the Node.js API. You can use it to eliminate your shell script's dependency on Unix while still keeping its familiar and powerful commands. You can also install it globally so you can run it from outside Node projects - say goodbye to those gnarly Bash scripts!
https://www.npmjs.com/package/node-cmd
https://www.npmjs.com/package/shelljs
have a look at this code may help u
var cmd=require('node-cmd');
cmd.get(
git clone https://github.com/RIAEvangelist/node-cmd.git
cd node-cmd
ls
,
function(data){
console.log('the node-cmd cloned dir contains these files :\n\n',data)
}
);
have look on this module
// starting a new repo
require('simple-git')()
.init()
.add('./*')
.commit("first commit!")
.addRemote('origin', 'https://github.com/user/repo.git')
.push('origin', 'master');
// push with -u
require('simple-git')()
.add('./*')
.commit("first commit!")
.addRemote('origin', 'some-repo-url')
.push(['-u', 'origin', 'master'], function () {
// done.
});
https://www.npmjs.com/package/simple-git

Resources