Method: Kernel#system
- Defined in:
- process.c
#system([env, ], options = {}, exception: false) ⇒ true, ... #system([env, ], *args, options = {}, exception: false) ⇒ true, ...
Creates a new child process by doing one of the following in that process:
-
Passing string
command_line
to the shell. -
Invoking the executable at
exe_path
.
This method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Returns:
-
true
if the command exits with status zero. -
false
if the exit status is a non-zero integer. -
nil
if the command could not execute.
Raises an exception (instead of returning false
or nil
) if keyword argument exception
is set to true
.
Assigns the command’s error status to $?
.
The new process is created using the system system call; it may inherit some of its environment from the calling program (possibly including open file descriptors).
Argument env
, if given, is a hash that affects ENV
for the new process; see Execution Environment.
Argument options
is a hash of options for the new process; see Execution Options.
The first required argument is one of the following:
-
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more meta characters. -
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
system('if true; then echo "Foo"; fi') # => true # Shell reserved word.
system('exit') # => true # Built-in.
system('date > /tmp/date.tmp') # => true # Contains meta character.
system('date > /nop/date.tmp') # => false
system('date > /nop/date.tmp', exception: true) # Raises RuntimeError.
Assigns the command’s error status to $?
:
system('exit') # => true # Built-in.
$? # => #<Process::Status: pid 640610 exit 0>
system('date > /nop/date.tmp') # => false
$? # => #<Process::Status: pid 640742 exit 2>
The command line may also contain arguments and options for the command:
system('echo "Foo"') # => true
Output:
Foo
See Execution Shell for details about the shell.
Raises an exception if the new process could not execute.
Argument exe_path
Argument exe_path
is one of the following:
-
The string path to an executable to be called.
-
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
system('/usr/bin/date') # => true # Path to date on Unix-style system.
system('foo') # => nil # Command failed.
Output:
Mon Aug 28 11:43:10 AM CDT 2023
Assigns the command’s error status to $?
:
system('/usr/bin/date') # => true
$? # => #<Process::Status: pid 645605 exit 0>
system('foo') # => nil
$? # => #<Process::Status: pid 645608 exit 127>
Ruby invokes the executable directly. This form does not use the shell; see Arguments args for caveats.
system('doesnt_exist') # => nil
If one or more args
is given, each is an argument or option to be passed to the executable:
system('echo', 'C*') # => true
system('echo', 'hello', 'world') # => true
Output:
C*
hello world
Raises an exception if the new process could not execute.
4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 |
# File 'process.c', line 4845
static VALUE
rb_f_system(int argc, VALUE *argv, VALUE _)
{
rb_thread_t *th = GET_THREAD();
VALUE execarg_obj = rb_execarg_new(argc, argv, TRUE, TRUE);
struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
struct rb_process_status status = {0};
eargp->status = &status;
last_status_clear(th);
// This function can set the thread's last status.
// May be different from waitpid_state.pid on exec failure.
rb_pid_t pid = rb_execarg_spawn(execarg_obj, 0, 0);
if (pid > 0) {
VALUE status = rb_process_status_wait(pid, 0);
struct rb_process_status *data = rb_check_typeddata(status, &rb_process_status_type);
// Set the last status:
rb_obj_freeze(status);
th->last_status = status;
if (data->status == EXIT_SUCCESS) {
return Qtrue;
}
if (data->error != 0) {
if (eargp->exception) {
VALUE command = eargp->invoke.sh.shell_script;
RB_GC_GUARD(execarg_obj);
rb_syserr_fail_str(data->error, command);
}
else {
return Qnil;
}
}
else 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, data->status), ": ");
rb_str_append(str, command);
RB_GC_GUARD(execarg_obj);
rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, str));
}
else {
return Qfalse;
}
RB_GC_GUARD(status);
}
if (eargp->exception) {
VALUE command = eargp->invoke.sh.shell_script;
RB_GC_GUARD(execarg_obj);
rb_syserr_fail_str(errno, command);
}
else {
return Qnil;
}
}
|