From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10233 invoked by alias); 3 May 2012 15:24:15 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 17055 Received: (qmail 15883 invoked from network); 3 May 2012 15:24:03 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 Received-SPF: none (ns1.primenet.com.au: domain at closedmail.com does not designate permitted sender hosts) From: Bart Schaefer Message-id: <120503082329.ZM13981@torch.brasslantern.com> Date: Thu, 03 May 2012 08:23:29 -0700 In-reply-to: Comments: In reply to TJ Luoma "a 'require' function for zsh scripts and interactive functions" (May 3, 9:56am) References: X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-users@zsh.org Subject: Re: a 'require' function for zsh scripts and interactive functions MIME-version: 1.0 Content-type: text/plain; charset=us-ascii Att'n zsh-workers: Possible bug noted at the very end of this reply. On May 3, 9:56am, TJ Luoma wrote: > > I'm trying to come up with a function which will allow me to 'require' > that a given command is found in $PATH, so I can put a line at the top > of a script like this: Wow, something did horrible things to your cut-and-paste. I won't try to excerpt your function here, but all leading whitespace is gone, and no line wrapping in your paragraphs (I've reformatted the excerpts). It looks like a bad html-to-text conversion. > The SHLVL is intended to keep my login shell from exiting if a > function doesn't find a required command. More on this in a moment ... > The : in the if/else/fi is because I wasn't sure how else to do a > "not" for (( $+commands[$UTIL] )) That one is simple: if ! (( $+commands[$UTIL] )) or if (( $+commands[$UTIL] == 0 )) > When I finished creating `require`, I found myself wondering if I had > just reinvented a wheel that zsh already implemented some other way, Look at the ${param:?message} expansion. ${NAME?WORD} ${NAME:?WORD} In the first form, if NAME is set, or in the second form if NAME is both set and non-null, then substitute its value; otherwise, print WORD and exit from the shell. Interactive shells instead return to the prompt. If WORD is omitted, then a standard message is printed. The only tickler is that NAME and WORD aren't expanded in the output: % print ${commands[$UTIL]?:No $UTIL found} zsh: commands[$UTIL]: No $UTIL found So your function is probably as good as anything, but if you want to take advantage of the special behavior of :? for interactive shells you can start with something like this: require () { setopt localtraps for UTIL do trap "msg 'No $UTIL found'" EXIT : ${commands[$UTIL]:?require failed} done trap - EXIT } There's one more gotcha with that which may be a bug: The EXIT trap is skipped when the function returns with 'require failed' (but still run by non-interactive shells when an actual exit occurs). So you may have to play around with "eval" and quoting to get decent output in your terminal, but for non-interactive shells growl will pop up. -- Barton E. Schaefer