Function: tramp-find-file-exists-command

tramp-find-file-exists-command is a byte-compiled function defined in tramp-sh.el.gz.

Signature

(tramp-find-file-exists-command VEC)

Documentation

Find a command on the remote host for checking if a file exists.

Here, we are looking for a command which has zero exit status if the file exists and nonzero exit status otherwise.

Source Code

;; Defined in /usr/src/emacs/lisp/net/tramp-sh.el.gz
;; ------------------------------------------------------------
;; -- Communication with external shell --
;; ------------------------------------------------------------

(defun tramp-find-file-exists-command (vec)
  "Find a command on the remote host for checking if a file exists.
Here, we are looking for a command which has zero exit status if the
file exists and nonzero exit status otherwise."
  (let ((existing "/")
        (nonexistent
	 (tramp-shell-quote-argument "/ this file does not exist "))
	result)
    ;; The algorithm is as follows: we try a list of several commands.
    ;; For each command, we first run `$cmd /' -- this should return
    ;; true, as the root directory always exists.  And then we run
    ;; `$cmd /\ this\ file\ does\ not\ exist\ ', hoping that the file
    ;; indeed does not exist.  This should return false.  We use the
    ;; first command we find that seems to work.
    ;; The list of commands to try is as follows:
    ;; `test -e'          Some Bourne shells have a `test' builtin
    ;;                    which does not know the `-e' option.
    ;; `/bin/test -e'     For those, the `test' binary on disk normally
    ;;                    provides the option.  Alas, the binary
    ;;                    is sometimes `/bin/test' and sometimes it's
    ;;                    `/usr/bin/test'.
    ;; `/usr/bin/test -e' In case `/bin/test' does not exist.
    ;; `ls -d'            This works on most systems, but NetBSD 1.4
    ;;                    has a bug: `ls' always returns zero exit
    ;;                    status, even for files which don't exist.

    (unless (or
	     (ignore-errors
	       (and (setq result (format "%s -e" (tramp-get-test-command vec)))
		    (tramp-send-command-and-check
		     vec (format "%s %s" result existing))
		    (not (tramp-send-command-and-check
			  vec (format "%s %s" result nonexistent)))))
	     (ignore-errors
	       (and (setq result "/bin/test -e")
		    (tramp-send-command-and-check
		     vec (format "%s %s" result existing))
		    (not (tramp-send-command-and-check
			  vec (format "%s %s" result nonexistent)))))
	     (ignore-errors
	       (and (setq result "/usr/bin/test -e")
		    (tramp-send-command-and-check
		     vec (format "%s %s" result existing))
		    (not (tramp-send-command-and-check
			  vec (format "%s %s" result nonexistent)))))
	     ;; We cannot use `tramp-get-ls-command', this results in an infloop.
	     ;; (Bug#65321)
	     (ignore-errors
	       (and (setq result (format "ls -d >%s" (tramp-get-remote-null-device vec)))
		    (tramp-send-command-and-check
		     vec (format "%s %s" result existing))
		    (not (tramp-send-command-and-check
			  vec (format "%s %s" result nonexistent))))))
      (tramp-error
       vec 'file-error "Couldn't find command to check if file exists"))
    (tramp-set-file-property vec existing "file-exists-p" t)
    result))