[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [PATCH] latest ash has broken 'echo' command



>From Debian Policy Manual, version 3.0.1.1, 1999-08-16:

4.4 Scripts

 ...

 The standard shell interpreter `/bin/sh' may be a symbolic link to any
 POSIX compatible shell. Thus, shell scripts specifying `/bin/sh' as
 interpreter may only use POSIX features. If a script requires
 non-POSIX features from the shell interpreter, the appropriate shell
 has to be specified in the first line of the script (e.g.,
 `#!/bin/bash') and the package has to depend on the package providing
 the shell (unless the shell package is marked `Essential', e.g., in
 the case of bash).

 Restrict your script to POSIX features when possible so that it may
 use /bin/sh as its interpreter. If your script works with ash, it's
 probably POSIX compliant, but if you are in doubt, use /bin/bash.

 ...

3.3 System run levels
3.3.6 Example

  ...

  #!/bin/sh
  #
  # Original version by Robert Leslie
  # <rob@mars.org>, edited by iwj and cs

  test -x /usr/sbin/named || exit 0

  case "$1" in
  start)
  echo -n "Starting domain name service: named"
  start-stop-daemon --start --quiet --exec /usr/sbin/named
  echo "."
  ;;
  ...
  etc etc...

 Another example on which to base your /etc/init.d scripts is in
 /etc/init.d/skeleton.

3.5 Console messages

 ...

 The following formats must be used
   * when daemons get started.
     Use this format if your script starts one or more daemons. The
     output should look like this (a single line, no leading spaces):
          Starting <description>: <daemon-1> <daemon-2> <...> <daemon-n

     The <description> should describe the subsystem the daemon or set
     of daemons are part of, while <daemon-1> up to <daemon-n> denote
     each daemon's name (typically the file name of the program).
     For example, the output of /etc/init.d/lpd would look like:
                Starting printer spooler: lpd.
     This can be achieved by saying
                echo -n "Starting printer spooler: lpd"
                start-stop-daemon --start --quiet lpd
                echo "."
     in the script. If you have more than one daemon to start, you
     should do the following:
                echo -n "Starting remote file system services:"
                echo -n " nfsd"; start-stop-daemon --start --quiet nfsd
                echo -n " mountd"; start-stop-daemon --start --quiet
mountd
                echo -n " ugidd"; start-stop-daemon --start --quiet
ugidd
                echo
"."

------------------------------------------------------------------------
--

Now, I haven't read Posix, but it's pretty clear the intent of Debian
Policy is that /bin/sh should support echo -n, because otherwise all of
the Policy examples are wrong, as is /etc/init.d/skeleton (it uses echo
-n), and who knows how many other scripts on the system will break.

So, if Posix deprecates echo -n, fine; maybe the next version of Policy
should replace echo -n with printf in all the examples, and bugs should
be filed against every package which uses echo -n

Or, make ash support echo -n, like it does in slink.  If Posix allows
echo -n, then ash is not breaking Posix.  If part of the design goal
for ash is to be a lint for shell scripts: ie make sure they only use
Posix >required< features, then make it a multi-binary package, say
"ash" and "ash-strict", where "ash-strict" disallows echo -n.

The second option sounds easier to me.  I mean, right now, people can
just expect their system to work if they install an alternative
/bin/sh.  Shouldn't it?

I punched in a command to search my system for /bin/sh scripts which
use echo -n, and what package they come from:

 dpkg --search $(
  for file in /bin/* /sbin/* /usr/bin/* /usr/sbin/* /etc/init.d/* ; do
{
   head -1 $file | grep '#! */bin/sh' &>/dev/null ;
  } &>/dev/null && grep 'echo *-n' $file &>/dev/null && echo $file ;
done
 )

 makedev:     /sbin/MAKEDEV
 dhelp:       /usr/bin/dhelp
 a2ps:        /usr/bin/fixps
 libc6:       /usr/bin/glibcbug
 a2ps:        /usr/bin/psmandup
 a2ps:        /usr/bin/psset
 eggdrop:     /usr/bin/putegg
 sendmail:    /usr/bin/runq
 debianutils: /usr/bin/savelog
 tetex-bin:   /usr/bin/texconfig
 kbd:         /usr/bin/unicode_start
 kbd:         /usr/bin/unicode_stop
 gzip:        /usr/bin/zless
 gzip:        /usr/bin/zmore
 cruft:       /usr/sbin/cruft
 cvs:         /usr/sbin/cvsconfig
 debsums:     /usr/sbin/debsums_gen
 esound:      /usr/sbin/esdconfig
 fdutils:     /usr/sbin/fdutilsconfig
 gpm:         /usr/sbin/gpmconfig
 diversion by libpaperg from: /usr/sbin/paperconfig
 diversion by libpaperg to: /usr/sbin/paperconfig.libc5
 libpaperg:   /usr/sbin/paperconfig
 samba:       /usr/sbin/sambaconfig
 sendmail:    /usr/sbin/sendmailconfig
 menu:        /usr/sbin/su-to-root
 tetex-bin:   /usr/sbin/texconfig
 libc6:       /usr/sbin/tzconfig
 ispell:      /usr/sbin/update-ispell-dictionary
 acct:        /etc/init.d/acct
 apache:      /etc/init.d/apache
 apache-ssl:  /etc/init.d/apache-ssl
 at:          /etc/init.d/atd
 bind:        /etc/init.d/bind
 kbd:         /etc/init.d/console-screen.kbd.sh
 cron:        /etc/init.d/cron
 gpm:         /etc/init.d/gpm
 netbase:     /etc/init.d/inetd
 login:       /etc/init.d/logoutd
 lpr:         /etc/init.d/lpd
 modutils:    /etc/init.d/modutils
 msqld:       /etc/init.d/msqld
 netstd:      /etc/init.d/netstd_init
 netstd:      /etc/init.d/netstd_misc
 netbase:     /etc/init.d/networking
 nfs-client:  /etc/init.d/nfs-client
 nfs-common:  /etc/init.d/nfs-common
 nvi:         /etc/init.d/nviboot
 oidentd:     /etc/init.d/oidentd
 netbase:     /etc/init.d/portmap
 ppp:         /etc/init.d/ppp
 quota:       /etc/init.d/quota
 sysvinit:    /etc/init.d/reboot
 samba:       /etc/init.d/samba
 sendmail:    /etc/init.d/sendmail
 sysvinit:    /etc/init.d/sendsigs
 sysvinit:    /etc/init.d/single
 sysvinit:    /etc/init.d/skeleton
 snmpd:       /etc/init.d/snmpd
 ssh:         /etc/init.d/ssh
 sysklogd:    /etc/init.d/sysklogd
 sysvinit:    /etc/init.d/umountfs
 uptimed:     /etc/init.d/uptimed
 sysvinit:    /etc/init.d/urandom
 wu-ftpd:     /etc/init.d/wu-ftpd

Cheers!
Eric

On (null), (null) wrote:

>> On Mon, Oct 25, 1999 at 11:44:38AM +0200, Marek Habersack wrote:
>> >
>> > You keep repeating this argument, but so far you haven't presented us the
>> > relevant fragment of the standard that specifically forbids the behavior.
>> 
>> OK, this is the last time that I'll spell it out to you.  I'm in this debate
>> because I maintain a package called ash.  That package exists for the sole
>> purpose of acting as /bin/sh.  That is only possible if all #!/bin/sh scripts
>> were restricted by some standard.  This currently happens to be POSIX.
>
>I think that some of us see your point, and your argument, but just 
>don't agree with it.
>
>Let me state what I think the facts are that we can all agree on:
>
>\beginfacts
>
>F1. POSIX defines the use of the "-n" flag to echo(1) as an optional 
>feature for suppressing the terminating newline at the of the echo(1)ed 
>string.
>
>F2. Because "echo -n" is optional, portable #!/bin/sh scripts cannot 
>rely on its existance for proper operation.  POSIX recommends printf(1) 
>as an alternative that is more flexible than "echo".
>
>F3. Currently, most Debian echo(1) commands, including /bin/echo, shell 
>builtins for bash and ksh, and probably others, support "echo -n".  
>[Ash is the only exception I know of.]
>
>F4. Several installed scripts in Debian that specify #!/bin/sh use the 
>"echo -n" construct.
>
>F5. Bash supports several features, colloquially known as "bashisms" 
>that are neither required nor specified as optional in POSIX.  It is 
>currently against Debian policy for installed scripts that specify 
>#!/bin/sh to use bashisms.  Bashisms are allowed if #!/bin/bash is 
>specified.
>
>Please note that I am not including POSIX-optional features in my 
>definition of "bashisms".  If F1 is true, then by my definition, "echo 
>-n" is -not- a bashism.
>
>\endfacts
>
>What I don't know, what I have questions about, include:
>
>\beginquestions
>
>Q1. Does the relevant POSIX document include echo(1) as part of the 
>shell, or does it assume that it is discussing /bin/echo, or is it 
>neutral on the matter (e.g., does it discuss an "environment", which 
>includes echo(1), but doesn't bias towards any particular 
>implementation).
>
>Q1a. If it assuming /bin/echo, and shells implement it as a builtin for 
>convenience and speed, shouldn't the shells try to match the behavior 
>of the existing /bin/echo?
>
>Q1b. Can ash completely remove support for echo(1) as a shell builtin 
>without violating policy or POSIX?  That would mean that echo(1) would 
>be provided by /bin/echo when running ash.
>
>Q2. Can a POSIX-compliant #!/bin/sh script use optional POSIX features 
>(like "echo -n") in environments where they are known to exist?  
>Granted, such a POSIX-compliant script won't be -portable-.
>
>\endquestions
>
>My personal opinion is that the answer to 2 is yes, and that based on 
>F3, Debian would qualify as an environment where the optional POSIX 
>feature of "echo -n" is known to exist.  Removing support for "echo -n" 
>is going contrary to established practice in Debian, and is not 
>required by POSIX.
>
>Explicitly specifying that "echo -n" is known to exist in policy may be 
>a good idea.
>
>-- 
>     Buddha Buck                      bmbuck@zaphod.dhis.edu
>"Just as the strength of the Internet is chaos, so the strength of our
>liberty depends upon the chaos and cacophony of the unfettered speech
>the First Amendment protects."  -- A.L.A. v. U.S. Dept. of Justice
>
>
>
>-- 
>To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
>with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
>



Reply to: