<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:admin="http://webns.net/mvcb/"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
	<channel> 

	<title>Comments on: bourne shell == line noise</title>
	<link>http://ask.metafilter.com/59222/bourne-shell-line-noise/</link>
	<description>Comments on Ask MetaFilter post bourne shell == line noise</description>
	<pubDate>Thu, 22 Mar 2007 15:38:34 -0800</pubDate>
	<lastBuildDate>Thu, 22 Mar 2007 15:38:34 -0800</lastBuildDate>
	<language>en-us</language>
	<docs>http://blogs.law.harvard.edu/tech/rss</docs>
	<ttl>60</ttl>

	<item>
		<title>Question: bourne shell == line noise</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise</link>	
		<description>Please help me understand what this OS X shell script is doing. &lt;br /&gt;&lt;br /&gt; On OS X 10.4, the &apos;cd&apos; command is a shell script in /usr/bin/cd:&lt;br&gt;
&lt;br&gt;
#!/bin/sh&lt;br&gt;
${0##*/} ${1+&quot;$@&quot;}&lt;br&gt;
&lt;br&gt;
Can someone explain it to me?</description>
		<guid isPermaLink="false">post:ask.metafilter.com,2007:site.59222</guid>
		<pubDate>Thu, 22 Mar 2007 15:31:56 -0800</pubDate>
		<dc:creator>Armitage Shanks</dc:creator>
		
			<category>osx</category>
		
			<category>cd</category>
		
			<category>bourne</category>
		
			<category>shell</category>
		
	</item> <item>
		<title>By: edd</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890435</link>	
		<description>cd&apos;s a builtin command in the shell. It&apos;s calling the builtin sh cd command with the argument. Presumably it&apos;s there for use when you&apos;re not in a shell environment to cd inside.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890435</guid>
		<pubDate>Thu, 22 Mar 2007 15:38:34 -0800</pubDate>
		<dc:creator>edd</dc:creator>
	</item><item>
		<title>By: edd</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890443</link>	
		<description>I should clarify that the first argument is the name of the script, so this is the same script that handles fg, alias and other otherwise-builtin commands - you can see that it just repeats what you put in if you copy it elsewhere, put an &apos;echo&apos; in before it, and run it from the other location.&lt;br&gt;
&lt;br&gt;
Also, on poking more knowledgeable types the ##*/ is responsible for eliminating the path if you try to put one in, so /usr/bin/cd gets reduced down to just cd. Not too sure about the nature of the thing that provides the arguments.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890443</guid>
		<pubDate>Thu, 22 Mar 2007 15:47:50 -0800</pubDate>
		<dc:creator>edd</dc:creator>
	</item><item>
		<title>By: donpardo</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890444</link>	
		<description>&lt;a href=&quot;http://www.cims.nyu.edu/cgi-comment/man.cgi?section=1&amp;topic=cd&quot;&gt;cd&lt;/a&gt;</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890444</guid>
		<pubDate>Thu, 22 Mar 2007 15:48:12 -0800</pubDate>
		<dc:creator>donpardo</dc:creator>
	</item><item>
		<title>By: Aidan Kehoe</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890450</link>	
		<description>&lt;a href=&quot;http://ask.metafilter.com/59222/bourne-shell-line-noise#890435&quot;&gt;edd,&lt;/a&gt; yes, &lt;blockquote&gt;&lt;i&gt;cd&apos;s a builtin command in the shell.&lt;/i&gt;&lt;/blockquote&gt;and indeed, it has to be&#8212;the script is puzzling, since to my knowledge it can&apos;t change the working directory of its parent process without using some application-specific IPC to do so, and as such, what it does is start a new shell, change that shell&apos;s current directory to the specified directory, then exit from it, returning to the parent shell, with the original working directory. Useless.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890450</guid>
		<pubDate>Thu, 22 Mar 2007 15:53:51 -0800</pubDate>
		<dc:creator>Aidan Kehoe</dc:creator>
	</item><item>
		<title>By: Aidan Kehoe</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890451</link>	
		<description>&lt;blockquote&gt;&lt;i&gt;I should clarify that the first argument is the name of the script, so this is the same script that handles fg, alias and other otherwise-builtin commands - you can see that it just repeats what you put in if you copy it elsewhere, put an &apos;echo&apos; in before it, and run it from the other location.&lt;/i&gt;&lt;/blockquote&gt; Ah, okay, so it may have been linked to cd because someone thought it sensible to provide shell script versions of &lt;i&gt;all&lt;/i&gt; the built-in commands, even where that made no sense.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890451</guid>
		<pubDate>Thu, 22 Mar 2007 15:55:44 -0800</pubDate>
		<dc:creator>Aidan Kehoe</dc:creator>
	</item><item>
		<title>By: edd</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890455</link>	
		<description>Ah yes, good point, but as donpardo&apos;s link points out it can be used to check if you can cd into a directory, even if it doesn&apos;t actually get the parent there.&lt;br&gt;
&lt;br&gt;
Another knowledgeable type tells me that the noise in the second argument is to help deal with no argument. It stops attempts to do a &apos;cd &quot;&quot;&apos; if you don&apos;t give a second argument in some cases, and just does the &apos;cd&apos; instead.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890455</guid>
		<pubDate>Thu, 22 Mar 2007 15:59:33 -0800</pubDate>
		<dc:creator>edd</dc:creator>
	</item><item>
		<title>By: vacapinta</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890457</link>	
		<description>Can&apos;t it be used to see if cd&apos;ing to a specific directory is possible (by branching on the return code) before attempting to cd to that directory?</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890457</guid>
		<pubDate>Thu, 22 Mar 2007 16:00:29 -0800</pubDate>
		<dc:creator>vacapinta</dc:creator>
	</item><item>
		<title>By: Freaky</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890461</link>	
		<description>${0##*/} -&amp;gt; $0 expands to the name of the script, ## removes the largest prefix pattern, and */ tells it to match until the last / in the string: this turns &quot;/usr/bin/cd&quot; into &quot;cd&quot;.&lt;br&gt;
&lt;br&gt;
${1+&quot;$@&quot;} -&amp;gt; test if $1 (first argument) is unset, if not, expand the argument list ($@) without field spliting (so you don&apos;t expand &quot;cd /foo\ bar/&quot; into &quot;cd &apos;/foo&apos; &apos;bar/&apos;&quot;)&lt;br&gt;
&lt;br&gt;
man sh :)</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890461</guid>
		<pubDate>Thu, 22 Mar 2007 16:08:12 -0800</pubDate>
		<dc:creator>Freaky</dc:creator>
	</item><item>
		<title>By: dmd</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890506</link>	
		<description>It may shed some light on this situation if one knows that /usr/bin/alias, bg, cd, command, fc, fg, getopts, hash, jobs, read, type, ulimit, umask, unalias, and wait ALL look like this on OSX:&lt;br&gt;
&lt;br&gt;
&lt;pre&gt;&lt;br&gt;
#!/bin/sh&lt;br&gt;
# $FreeBSD: src/usr.bin/alias/generic.sh,v 1.1 2002/07/16 22:16:03 wollman Exp $&lt;br&gt;
# This file is in the public domain.&lt;br&gt;
${0##*/} ${1+&quot;$@&quot;}&lt;br&gt;
&lt;/pre&gt;</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890506</guid>
		<pubDate>Thu, 22 Mar 2007 16:51:57 -0800</pubDate>
		<dc:creator>dmd</dc:creator>
	</item><item>
		<title>By: Armitage Shanks</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890518</link>	
		<description>&lt;i&gt;It may shed some light on this situation if one knows that /usr/bin/alias, bg, cd, command, fc, fg, getopts, hash, jobs, read, type, ulimit, umask, unalias, and wait ALL look like this on OSX:&lt;/i&gt;&lt;br&gt;
&lt;br&gt;
Interesting.  It appears that none of these files exist in 10.3.  &lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://freebsd.monkey.org/freebsd-cvs-all/200510/msg04142.html&quot;&gt;Here&apos;s a checkin&lt;/a&gt; I found for the file generic.sh on FreeBSD that may explain it (it confuses me even more, to be honest):&lt;blockquote&gt;Use the &quot;builtin&quot; shell function to make sure that the requested&lt;br&gt;
  command is handled as a shell function.  This avoids the following&lt;br&gt;
  peculiar behaviour when /usr/bin is on a case-insensitive filesystem:&lt;br&gt;
      # READ foo&lt;br&gt;
  (... long pause, depending upon the amount of swap space available ...)&lt;br&gt;
      sh: Resource temporarily unavailable.&lt;/blockquote&gt;</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890518</guid>
		<pubDate>Thu, 22 Mar 2007 17:00:21 -0800</pubDate>
		<dc:creator>Armitage Shanks</dc:creator>
	</item><item>
		<title>By: cmiller</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890524</link>	
		<description>&lt;tt&gt;cmiller@calliope:~ $ /usr/bin/cd /tmp&lt;br&gt;
cmiller@calliope:~ $&lt;br&gt;
&lt;/tt&gt;&lt;br&gt;
Indeed, what a strange little program.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890524</guid>
		<pubDate>Thu, 22 Mar 2007 17:03:44 -0800</pubDate>
		<dc:creator>cmiller</dc:creator>
	</item><item>
		<title>By: Armitage Shanks</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890538</link>	
		<description>Damn, this gets weirder all the time:&lt;blockquote&gt;$ which cd&lt;br&gt;
/usr/bin/cd&lt;br&gt;
$ which CD&lt;br&gt;
/usr/bin/CD&lt;br&gt;
$ cd&lt;br&gt;
$ CD&lt;br&gt;
/usr/bin/CD: fork: Resource temporarily unavailable&lt;br&gt;
&lt;/blockquote&gt;If I edit /usr/bin/cd and add an &quot;echo FOO&quot; to it, when I execute &quot;CD&quot; (in caps), it goes into  an infinite loop printing &quot;FOO&quot; until it runs out of processes.  So it seems like it&apos;s  not even preventing the problem it was meant to.  Wtf.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890538</guid>
		<pubDate>Thu, 22 Mar 2007 17:16:09 -0800</pubDate>
		<dc:creator>Armitage Shanks</dc:creator>
	</item><item>
		<title>By: Armitage Shanks</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890545</link>	
		<description>Actually, it seems to *introduce* the problem.  On 10.3, if you try to run any of the builtins in caps, i.e.&lt;br&gt;
&lt;br&gt;
CD&lt;br&gt;
ALIAS&lt;br&gt;
UNALIAS&lt;br&gt;
etc&lt;br&gt;
&lt;br&gt;
you just get &quot;command not found&quot;.  On 10.4, they all eventually run out of resources because the shell script version is presumably invoking itself recursively.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890545</guid>
		<pubDate>Thu, 22 Mar 2007 17:23:47 -0800</pubDate>
		<dc:creator>Armitage Shanks</dc:creator>
	</item><item>
		<title>By: Freaky</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890681</link>	
		<description>Yes, that&apos;s why the builtin function was added to it; builtin lookup is case-sensitive, so if filename lookup isn&apos;t, and you don&apos;t use the same case as the builtin to call the script, you get stuck in a loop as it tries to run $0.  Explicitly telling the shell to use a builtin fixes this:&lt;br&gt;
&lt;br&gt;
&lt;tt&gt;#!/bin/sh&lt;br&gt;
# $FreeBSD: src/usr.bin/alias/generic.sh,v 1.1.16.1 2005/11/04 18:21:37 cperciva Exp $&lt;br&gt;
# This file is in the public domain.&lt;br&gt;
builtin ${0##*/} ${1+&quot;$@&quot;}&lt;/tt&gt;&lt;br&gt;
&lt;br&gt;
You crazy kids and your case-insensitive filesystems, you&apos;ll get us all killed!</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890681</guid>
		<pubDate>Thu, 22 Mar 2007 19:45:00 -0800</pubDate>
		<dc:creator>Freaky</dc:creator>
	</item><item>
		<title>By: flabdablet</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890688</link>	
		<description>I still don&apos;t understand why&lt;br&gt;
&lt;code&gt;&lt;br&gt;
${1+&quot;$@&quot;}&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
works.  I mean, it clearly does, but all the sh and bash manuals I&apos;ve ever seen say that the proper syntax for this should be&lt;br&gt;
&lt;code&gt;&lt;br&gt;
${1:+&quot;$@&quot;} &lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Is the first form just a terribly-old-skool version of the second?</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890688</guid>
		<pubDate>Thu, 22 Mar 2007 19:53:41 -0800</pubDate>
		<dc:creator>flabdablet</dc:creator>
	</item><item>
		<title>By: Armitage Shanks</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#890690</link>	
		<description>&lt;i&gt;Yes, that&apos;s why the builtin function was added to it;&lt;/i&gt;&lt;br&gt;
&lt;br&gt;
Ah yes, I missed that, scratch my last two comments.&lt;br&gt;
&lt;br&gt;
OK, so the only thing I&apos;m not clear on is why /usr/bin equivalents for all these builtins (alias, bg, cd, command, fc, fg, getopts, hash, jobs, read, type, ulimit, umask, and unalias) were added in the first place.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-890690</guid>
		<pubDate>Thu, 22 Mar 2007 20:00:21 -0800</pubDate>
		<dc:creator>Armitage Shanks</dc:creator>
	</item><item>
		<title>By: Freaky</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#891219</link>	
		<description>&lt;cite&gt;&quot;all the sh and bash manuals I&apos;ve ever seen say that the proper syntax for this should be&lt;br&gt;
&lt;br&gt;
${1:+&quot;$@&quot;} &lt;br&gt;
&lt;br&gt;
Is the first form just a terribly-old-skool version of the second?&quot;&lt;/cite&gt;&lt;br&gt;
&lt;br&gt;
Nope; it changes the behavior wrt null arguments, allowing for the expansion of empty strings.  From sh(1):&lt;br&gt;
&lt;br&gt;
&lt;tt&gt;     ${parameter:+word}&lt;br&gt;
Use Alternate Value.  If parameter is unset or null, null is substituted; otherwise, the expansion of word is substituted.&lt;br&gt;
&lt;br&gt;
In the parameter expansions shown previously, use of the colon in the format results in a test for a parameter that is unset or null; &lt;strong&gt;omission of the colon results in a test for a parameter that is only unset&lt;/strong&gt;.&lt;/tt&gt;&lt;br&gt;
&lt;br&gt;
You can see this behavior on a simple script like:&lt;br&gt;
&lt;br&gt;
&lt;tt&gt;#!/bin/sh&lt;br&gt;
ruby -e &apos;p ARGV&apos; ${1+&quot;$@&quot;}&lt;br&gt;
ruby -e &apos;p ARGV&apos; ${1:+&quot;$@&quot;}&lt;/tt&gt;&lt;br&gt;
&lt;br&gt;
When ran with ./foo.sh &apos; bla you get:&lt;br&gt;
&lt;br&gt;
&lt;tt&gt;[&quot;&quot;, &quot;bla&quot;]&lt;br&gt;
[]&lt;/tt&gt;&lt;br&gt;
&lt;br&gt;
-- the second doesn&apos;t get expanded because with the colon, there&apos;s nothing to distinguish an empty (null) argument and no argument (unset).&lt;br&gt;
&lt;br&gt;
As for their reason for existance, check the CVS logs: they&apos;re &lt;a href=&quot;http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/alias/generic.sh&quot;&gt;required by POSIX&lt;/a&gt;.  Well, that&apos;s why they&apos;re in FreeBSD (and by proxy why they&apos;re in MacOS X); why they&apos;re in POSIX I don&apos;t know ;)</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-891219</guid>
		<pubDate>Fri, 23 Mar 2007 11:11:24 -0800</pubDate>
		<dc:creator>Freaky</dc:creator>
	</item><item>
		<title>By: flabdablet</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#892240</link>	
		<description>Thanks for that, freaky.  You&apos;d think &lt;a href=&quot;http://ask.metafilter.com/28950/what-the-fuc&quot;&gt;I would have learned by now&lt;/a&gt; to read the sh manual with a fine tooth comb :-)&lt;br&gt;
&lt;br&gt;
Okay.  So &lt;strong&gt;${1+&quot;$@&quot;}&lt;/strong&gt; means &quot;if argument 1 is set to anything at all, substitute all arguments individually quoted&quot;.&lt;br&gt;
&lt;br&gt;
Then, because this happens inside an unquoted &lt;strong&gt;$1&lt;/strong&gt; expansion, the resulting value will be word-split. But because &lt;strong&gt;&quot;$@&quot;&lt;/strong&gt; generates individually quoted values, word-splitting will only occur on the boundaries between those quoted values; in effect, the expansion of the substituted &lt;strong&gt;$1&lt;/strong&gt; will be all  arguments, individually quoted.&lt;br&gt;
&lt;br&gt;
So why would anybody use this convoluted test-and-substitute construction instead of a bare &lt;strong&gt;&quot;$@&quot;&lt;/strong&gt;?  Can you think of an argument list that would make&lt;br&gt;
&lt;code&gt;&lt;br&gt;
#!/bin/sh&lt;br&gt;
ruby -e &apos;p ARGV&apos; ${1+&quot;$@&quot;}&lt;br&gt;
ruby -e &apos;p ARGV&apos; &quot;$@&quot;&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
print two different output lines?  I haven&apos;t been able to find one.</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-892240</guid>
		<pubDate>Sat, 24 Mar 2007 18:20:31 -0800</pubDate>
		<dc:creator>flabdablet</dc:creator>
	</item><item>
		<title>By: Freaky</title>
		<link>http://ask.metafilter.com/59222/bourne-shell-line-noise#892345</link>	
		<description>Pass; my reading of the manpage and tests suggest that indeed they&apos;re equivilent.  The scripts are pretty much utterly useless anyway, so I guess useless tests within them are to be expected ;)&lt;br&gt;
&lt;br&gt;
Maybe it&apos;s defensive, in case of a shell which doesn&apos;t expand &quot;$@&quot; properly in the zero-arguments case.&lt;br&gt;
&lt;br&gt;
Asking on a mailing list may get more detail.  *someone* on freebsd-*@freebsd.org probably knows ;)</description>
		<guid isPermaLink="false">comment:ask.metafilter.com,2007:site.59222-892345</guid>
		<pubDate>Sat, 24 Mar 2007 19:56:08 -0800</pubDate>
		<dc:creator>Freaky</dc:creator>
	</item>
	</channel>
</rss>
