Improve documentation of sending commands to shells
authorEli Zaretskii <eliz@gnu.org>
Sat, 25 May 2024 10:02:20 +0000 (13:02 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 25 May 2024 10:02:20 +0000 (13:02 +0300)
* 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)

doc/lispref/processes.texi
lisp/simple.el
lisp/subr.el

index c356c905dee76cd1b995a14dcf4a73a13658e220..c5fbb0fb81825d369f2b0830dbe814dcb4c622b2 100644 (file)
@@ -616,11 +616,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
@@ -944,6 +957,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
index bcd26da13edae370f6ca5e1fc8fab8d7131b0e22..5177905ee1b2f643d63de573d68b8fc48fc2ac43 100644 (file)
@@ -4928,7 +4928,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"))
@@ -5110,7 +5117,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))))
index d6481fdf73ec922ba5eff9782a5b84f25816b0ae..eda5b7ae31bcd935ff5df230378f6f21bf870129 100644 (file)
@@ -4782,7 +4782,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))