From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: (qmail 2369 invoked from network); 13 Apr 2020 14:23:59 -0000 Received-SPF: pass (primenet.com.au: domain of zsh.org designates 203.24.36.2 as permitted sender) receiver=inbox.vuxu.org; client-ip=203.24.36.2 envelope-from= Received: from ns1.primenet.com.au (HELO primenet.com.au) (203.24.36.2) by inbox.vuxu.org with UTF8ESMTPZ; 13 Apr 2020 14:23:59 -0000 Received: (qmail 14316 invoked by alias); 13 Apr 2020 14:23:46 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 45688 Received: (qmail 26909 invoked by uid 1010); 13 Apr 2020 14:23:46 -0000 X-Qmail-Scanner-Diagnostics: from relay10.mail.gandi.net by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.102.2/25779. spamassassin: 3.4.4. Clear:RC:0(217.70.178.230):SA:0(-2.6/5.0):. Processed in 3.834185 secs); 13 Apr 2020 14:23:46 -0000 X-Envelope-From: stephane@chazelas.org X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: pass (ns1.primenet.com.au: SPF record at _nblcust.gandi.net designates 217.70.178.230 as permitted sender) Date: Mon, 13 Apr 2020 15:22:57 +0100 From: Stephane Chazelas To: zsh-workers@zsh.org Subject: Re: glob qualifier '-' doesn't work correctly on dangling symlinks Message-ID: <20200413142257.orwzb4jrgmf7gpoi@chazelas.org> Mail-Followup-To: zsh-workers@zsh.org References: <20200411173450.56nnznxtmil5oge3@chazelas.org> <20200411191711.GA1722320@zira.vinc17.org> <20200411203714.wupg6wmd7b7xch2w@chazelas.org> <20200411234817.GA1737986@zira.vinc17.org> <20200412012155.7954a35f@tarpaulin.shahaf.local2> <20200412021722.GA1748686@zira.vinc17.org> <20200412070930.etfzj6j2qvd5em7b@chazelas.org> <20200412142544.GA1783815@zira.vinc17.org> <20200412173448.rl3wttigdx5t5wcn@chazelas.org> <20200412233845.GB1831017@zira.vinc17.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200412233845.GB1831017@zira.vinc17.org> User-Agent: NeoMutt/20180716 2020-04-13 01:38:45 +0200, Vincent Lefevre: [...] > > Well, as seen in the varying interpretations made by the various > > implementations, it is not that clear. How do you determine > > whether a file exists or not? What does "exist" mean? > > You necessarily know it, or that's an error case (permission denied > or whatever). The behavior may not be clear in case of error, but > one can expect at least a non-zero exit status: [...] Are you saying that EACCES is an "error" but ENOENT is not? How about ENOTDIR, ELOOP? None of /etc/passwd/foo, /etc/pesswd/foo, symloop/foo or /root/foo exist on my system, a stat() on a symlink to those would return ENOTDIR, ENOENT, ELOOP, EACCES. On which one should find -L return with a non-zero exit status? Which one(s) should find -L . -type l (or find . -xtype l) print? [...] > -e pathname > True if pathname resolves to an existing directory entry. > False if pathname cannot be resolved. > > BTW, I don't know how zsh behaves on "[[ -e pathname ]]" in case of > error other than ENOENT in the pathname resolution, but this should > be documented (and ditto for the other conditional expressions). [...] The mention of "directory entry" is misleading here. It's really about a "file" more than a "directory entry" as stat() gets you to the inode. Maybe: -e pathname True if pathname can be determined to resolve to an existing file (of any type). False otherwise. Note that since this applies after symlink resolution, that will return false for existing but broken symlinks. Use [[ -e /path/to/file || -L /path/to/file ]] to account for that (requires search access to the directory). But that's probably going to confuse the reader more than help them. To confuse them even more, we could also mention (){(($#))} (#I)/path/to/file(|)(N) to really check for file being an entry in /path/to (requires read access to the directory and extendedglob for (#I) used to cancel nocaseglob in case it's enabled). IIRC the "test" operator was initially "-a" (for "accessible"?) for that which was a bit more accurrate (or maybe it was a SYSV-sh vs ksh thing, I can't remember). See also https://stackoverflow.com/questions/638975/how-do-i-tell-if-a-regular-file-does-not-exist-in-bash/40046642#40046642 -- Stephane