From: Eli Zaretskii Date: Sat, 25 May 2024 10:02:20 +0000 (+0300) Subject: Improve documentation of sending commands to shells X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=3bab9e9e04fc3b20224c9d55123c08e62692d78e;p=emacs.git Improve documentation of sending commands to shells * doc/lispref/processes.texi (Synchronous Processes): * lisp/subr.el (call-shell-region): * lisp/simple.el (shell-command-on-region) (shell-command-to-string): Document system-dependent aspects of sending commands to shells. (Bug#71081) (cherry picked from commit d54178f535b1eafe4919a282cf85a9b553469de2) --- diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 7fe330b0e8c..6072f05524e 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -614,11 +614,24 @@ is similar than @code{call-process-region}, with process being a shell. The arguments @code{delete}, @code{destination} and the return value are like in @code{call-process-region}. Note that this function doesn't accept additional arguments. + +If @var{command} names a shell (e.g., via @code{shell-file-name}), keep +in mind that behavior of various shells when commands are piped to their +standard input is shell- and system-dependent, and thus non-portable. +The differences are especially prominent when the region includes more +than one line, i.e.@: when piping to a shell commands with embedded +newlines. Lisp programs using this technique will therefore need to +format the text in the region differently, according to the expectations +of the shell. @end defun @defun shell-command-to-string command This function executes @var{command} (a string) as a shell command, -then returns the command's output as a string. +then returns the command's output as a string. If @var{command} +actually includes more than one command, the behavior depends on the +shell to be invoked (determined by @code{shell-file-name} for local +commands). In particular, the separator between the commands cannot be +a newline on MS-Windows; use @samp{&&} instead. @end defun @c There is also shell-command-on-region, but that is more of a user @@ -942,6 +955,7 @@ example the function @code{ange-ftp-hook-function}). In such cases, this function does nothing and returns @code{nil}. @end defun +@vindex shell-file-name @defun start-process-shell-command name buffer-or-name command This function is like @code{start-process}, except that it uses a shell to execute the specified @var{command}. The argument diff --git a/lisp/simple.el b/lisp/simple.el index 8f4664200de..34ca26392aa 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -4978,7 +4978,14 @@ interactively, this is t. Non-nil REGION-NONCONTIGUOUS-P means that the region is composed of noncontiguous pieces. The most common example of this is a rectangular region, where the pieces are separated by newline -characters." +characters. + +If COMMAND names a shell (e.g., via `shell-file-name'), keep in mind +that behavior of various shells when commands are piped to their +standard input is shell- and system-dependent, and thus non-portable. +The differences are especially prominent when the region includes +more than one line, i.e. when piping to a shell commands with embedded +newlines." (interactive (let (string) (unless (mark) (user-error "The mark is not set now, so there is no region")) @@ -5160,7 +5167,13 @@ other cases, consider alternatives such as `call-process' or `process-lines', which do not invoke the shell. Consider using built-in functions like `rename-file' instead of the external command \"mv\". For more information, see Info node -`(elisp)Security Considerations'." +`(elisp)Security Considerations'. + +If COMMAND includes several separate commands to run one after +the other, the separator between the individual commands needs +to be shell- and system-dependent. In particular, the MS-Windows +shell cmd.exe doesn't support commands with embedded newlines; +use the \"&&\" separator instead." (with-output-to-string (with-current-buffer standard-output (shell-command command t)))) diff --git a/lisp/subr.el b/lisp/subr.el index b499cc0cff1..3b1145afdc2 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4786,7 +4786,14 @@ t (mix it with ordinary output), or a file name string. If BUFFER is 0, `call-shell-region' returns immediately with value nil. Otherwise it waits for COMMAND to terminate and returns a numeric exit status or a signal description string. -If you quit, the process is killed with SIGINT, or SIGKILL if you quit again." +If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. + +If COMMAND names a shell (e.g., via `shell-file-name'), keep in mind +that behavior of various shells when commands are piped to their +standard input is shell- and system-dependent, and thus non-portable. +The differences are especially prominent when the region includes +more than one line, i.e. when piping to a shell commands with embedded +newlines." (call-process-region start end shell-file-name delete buffer nil shell-command-switch command))