Package: dash
Version: 0.5.12-12
Severity: normal
Tags: upstream

Problem:

   set -- 1
   shift 2
   ... causes program to exit

The exit is a bit unexpected as the whole
program terminates. Suggested change:

   1. shift all positional parameters
   2. set status code $?
   3. continue execution

   This would also be allowed by POSIX:
   Bash and Zsh behaves like this. 

This would make it possible to write code:

   set -- 1
   if shift 2 ; then
      ... do something, a warning message to user ...
   fi
   ... continue

Caveat: I'm aware of this, but perhaps
the default behaviour with N could be
chnaged to be more script friendly.

     shift $#

See also attached test script.

CONSEQUENCES OF ERRORS

Program execution is interrupted and
program cannot do any error handling of
their own.

Ref: POSIX 2018 (shift):

    
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_25_01

    EXIT STATUS

    If the n operand is invalid or is greater than "$#", this may be
    considered a syntax error and a non-interactive shell may exit; if
    the shell does not exit in this case, a non-zero exit status shall
    be returned. Otherwise, zero shall be returned.

-- System Information:
Debian Release: trixie/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 6.1.0-6-amd64 (SMP w/4 CPU threads; PREEMPT)
Locale: LANG=C.UTF-8, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages dash depends on:
ii  debianutils  5.21
ii  libc6        2.40-6

dash recommends no packages.

dash suggests no packages.

-- debconf information:
  dash/ineffectivediversion:
* dash/sh: true
#! /bin/sh
# Short: POSIX shift N and $?
# Desc: Test POSIX Special Built-in support: shift N, when not enough args
# Url: 
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_26_01
#
# Notes:
#
# POSIX: "(...) If the n operand is invalid
# or is greater than `$#`, this may be
# considered a syntax error and a non-interactive
# shell may exit"
#
# Issues with `shift N` if there was not
# enough args to shift.
#
# Behaviour is not uniform accross shells.
# run this file under debug to see behavior.
#
#     $sh -x <file>
#
#     posh       : error and exit with code 1
#     dash       : error and exit with code 2
#     mksh       : error and exit with code 1
#     ksh93      : error and exit with code 1
#     busybox ash: no error message and $? is set to 1
#     bash       : no error message and $? is set to 1
#     zsh        : error messahe and $? is set to 1

test ()
(
    # Run test in subshell compound-list
    # to prevent premature exit call
    set -- 1
    shift 2
    echo "x$?"
)

file=t.ret

# ignore file redirection
# shellcheck disable=SC2065

if test > "$file"; then
    # Normal program execution
    code=$(cat "$file")
    code=${code#x}
    rm -f "$file"
    [ ! "$code" = 0 ]
else
    code=$?
    rm -f "$file"
    echo "FATAL: shift called exit $code"
    exit "$code"
fi

Reply via email to