Method: Kernel#system
- Defined in:
- process.c
#system([env,][,options], exception: false) ⇒ true, ...
Executes command… in a subshell. command… is one of following forms.
commandline
-
command line string which is passed to the standard shell
cmdname, arg1, ...
-
command name and one or more arguments (no shell)
[cmdname, argv0], arg1, ...
-
command name,
argv[0]
and zero or more arguments (no shell)
system returns true
if the command gives zero exit status, false
for non zero exit status. Returns nil
if command execution fails. An error status is available in $?
.
If the exception: true
argument is passed, the method raises an exception instead of returning false
or nil
.
The arguments are processed in the same way as for Kernel#spawn.
The hash arguments, env and options, are same as #exec and #spawn. See Kernel#spawn for details.
system("echo *")
system("echo", "*")
produces:
config.h main.rb
*
Error handling:
system("cat nonexistent.txt")
# => false
system("catt nonexistent.txt")
# => nil
system("cat nonexistent.txt", exception: true)
# RuntimeError (Command failed with exit 1: cat)
system("catt nonexistent.txt", exception: true)
# Errno::ENOENT (No such file or directory - catt)
See Kernel#exec for the standard shell.
4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 |
# File 'process.c', line 4732
static VALUE
rb_f_system(int argc, VALUE *argv, VALUE _)
{
/*
* n.b. using alloca for now to simplify future Thread::Light code
* when we need to use malloc for non-native Fiber
*/
struct waitpid_state *w = alloca(sizeof(struct waitpid_state));
rb_pid_t pid; /* may be different from waitpid_state.pid on exec failure */
VALUE execarg_obj;
struct rb_execarg *eargp;
int exec_errnum;
execarg_obj = rb_execarg_new(argc, argv, TRUE, TRUE);
eargp = rb_execarg_get(execarg_obj);
w->ec = GET_EC();
waitpid_state_init(w, 0, 0);
eargp->waitpid_state = w;
pid = rb_execarg_spawn(execarg_obj, 0, 0);
exec_errnum = pid < 0 ? errno : 0;
#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
if (w->pid > 0) {
/* `pid' (not w->pid) may be < 0 here if execve failed in child */
if (WAITPID_USE_SIGCHLD) {
rb_ensure(waitpid_sleep, (VALUE)w, waitpid_cleanup, (VALUE)w);
}
else {
waitpid_no_SIGCHLD(w);
}
rb_last_status_set(w->status, w->ret);
}
#endif
if (w->pid < 0 /* fork failure */ || pid < 0 /* exec failure */) {
if (eargp->exception) {
int err = exec_errnum ? exec_errnum : w->errnum;
VALUE command = eargp->invoke.sh.shell_script;
RB_GC_GUARD(execarg_obj);
rb_syserr_fail_str(err, command);
}
else {
return Qnil;
}
}
if (w->status == EXIT_SUCCESS) return Qtrue;
if (eargp->exception) {
VALUE command = eargp->invoke.sh.shell_script;
VALUE str = rb_str_new_cstr("Command failed with");
rb_str_cat_cstr(pst_message_status(str, w->status), ": ");
rb_str_append(str, command);
RB_GC_GUARD(execarg_obj);
rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, str));
}
else {
return Qfalse;
}
}
|