bug-bash
[Top][All Lists]
Advanced

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

$# equals 1 in scripts sourced with no arguments from a login shell when


From: Denis McKeon
Subject: $# equals 1 in scripts sourced with no arguments from a login shell when bash 1.x vars are set (was: last `set option value' always passed as $1 and $2 during a 'source' ??)
Date: Mon, 11 Jun 2001 16:58:48 -0700

Configuration Information [Automatically generated, do not change]:
Machine: i386
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i386' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i386-redhat-linux-gnu' 
-DCONF_VENDOR='redhat' -DSHELL -DHAVE_CONFIG_H  -D_GNU_SOURCE 
-D_FILE_OFFSET_BITS=64  -I.  -I. -I./include -I./lib -I/usr/include -O2 
-march=i386 -mcpu=i686
uname output: Linux p7 2.2.16-22 #1 Tue Aug 22 16:49:06 EDT 2000 i686 unknown
Machine Type: i386-redhat-linux-gnu

Bash Version: 2.04
Patch Level: 11
Release Status: release

Description: $# equals 1 in scripts sourced with no arguments from a login 
shell when bash 1.x vars are set

This presented when I wanted to have a script be source'd and then
iterate over its arguments, if any, but when trying to test the number
of args to the script, found: $# -eq 1 && "$1" == "command_oriented_history"

This is a different manifestation of the problem Philip posted about,
caused in this case by a left-over relic in a bash v1 ~/.bash_profile.

Repeat-By: short version:  source this:
echo -n '$#:'$#': $1:' ; if [ $# -gt 0 ] ; then echo -n $1 ; fi ; echo ':'
then: set command_oriented_history
and source it again.

long version: see log as cut & pasted below (attempting to reproduce
this sequence in a sub-shell, such as with script(1), may fail,
depending on what is 'set' in the sub-script.)
# my interpolated comments are right of # marks

login: username
Password:

$ bash -version
GNU bash, version 2.04.11(1)-release (i386-redhat-linux-gnu)
Copyright 1999 Free Software Foundation, Inc.

# nothing is set by the user
$ ls -l .bash{rc,_profile}
ls: .bashrc: No such file or directory
ls: .bash_profile: No such file or directory

# if these settings matter ...
$ echo ":$sourced:$SHELLOPTS:"
:1:braceexpand:hashall:histexpand:monitor:history:interactive-comments:emacs:

# loosely based on script previously posted by
# Philip Lijnzaad <address@hidden>

$ cat script
echo -n in arg0 :$0: with dollarhash :$#:
[ $# -gt 0 ] && echo -n " and dollarat:$@:"
    let a=0
# replacing "$@" with address@hidden"$@"} did not seem to change the result
    for arg in "$@" ; do
        let $((a++))
        echo -n  " arg $((a)):$arg:"
    done
    echo ""

$ cat calls
     ./script a1 a2
     ./script
source script a1 a2
source script

$ ./calls
in arg0 :./script: with dollarhash :2: and dollarat:a1 a2: arg 1:a1: arg 2:a2:
in arg0 :./script: with dollarhash :0:
in arg0 :./calls: with dollarhash :2: and dollarat:a1 a2: arg 1:a1: arg 2:a2:
in arg0 :./calls: with dollarhash :0:

$ source ./calls
in arg0 :./script: with dollarhash :2: and dollarat:a1 a2: arg 1:a1: arg 2:a2:
in arg0 :./script: with dollarhash :0:
in arg0 :-bash: with dollarhash :2: and dollarat:a1 a2: arg 1:a1: arg 2:a2:
in arg0 :-bash: with dollarhash :0:

$ source script a1 a2
in arg0 :-bash: with dollarhash :2: and dollarat:a1 a2: arg 1:a1: arg 2:a2:

$ source script
in arg0 :-bash: with dollarhash :0:

# a relic from bash 1.x
$ set command_oriented_history

$ ./calls
in arg0 :./script: with dollarhash :2: and dollarat:a1 a2: arg 1:a1: arg 2:a2:
in arg0 :./script: with dollarhash :0:
in arg0 :./calls: with dollarhash :2: and dollarat:a1 a2: arg 1:a1: arg 2:a2:
in arg0 :./calls: with dollarhash :0:

$ source ./calls
in arg0 :./script: with dollarhash :2: and dollarat:a1 a2: arg 1:a1: arg 2:a2:
in arg0 :./script: with dollarhash :0:
in arg0 :-bash: with dollarhash :2: and dollarat:a1 a2: arg 1:a1: arg 2:a2:
in arg0 :-bash: with dollarhash :1: and dollarat:command_oriented_history: arg 
1:command_oriented_history:
-------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^--------^^^^^^^^^^^^^^^^^^^^^^^^

$ source script a1 a2
in arg0 :-bash: with dollarhash :2: and dollarat:a1 a2: arg 1:a1: arg 2:a2:

$ source script
in arg0 :-bash: with dollarhash :1: and dollarat:command_oriented_history: arg 
1:command_oriented_history:
-------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^--------^^^^^^^^^^^^^^^^^^^^^^^^

# It seems like the underlined results should be:
# 
# in arg0 :-bash: with dollarhash :0:
# 
# or if not, why not?

# attempts to turn off the behavior

$ unset command_oriented_history

$ source script
in arg0 :-bash: with dollarhash :1: and dollarat:command_oriented_history: arg 
1:command_oriented_history:
-------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^--------^^^^^^^^^^^^^^^^^^^^^^^^

$ echo ":$command_oriented_history:"
::

$ command_oriented_history=

$ echo ":$command_oriented_history:"
::

$ source script
in arg0 :-bash: with dollarhash :1: and dollarat:command_oriented_history: arg 
1:command_oriented_history:
-------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^--------^^^^^^^^^^^^^^^^^^^^^^^^

Fix: 0) don't source scripts that examine their arguments

     1) hack bash 2.x to warn about attempts to set legendary bash 1.x vars

     2) replace "set command_oriented_history" and similar sets 
        with "shopt -s cmdhist" and equivalents.  
        
    The need to make this change apparently was documented in a bash2.02
    README file, as found in:  http://socrates.berkeley.edu/News/

> 7. Some variables have been removed: MAIL_WARNING, notify,
> history_control, command_orientedhistory, glob_dot_filenames,
> allow_nullglob_expansion, nolinks, hostname_completionfile, noclobber,
> no_exit_onfailed_exec, and cdable_vars. Most of them are now implemented
> with the new `shopt' builtin; others were already implemented by `set'. 
> Here is a list of correspondences: 
> 
>   MAIL_WARNING                    shopt mailwarn
>   notify                          set -o notify
>   history_control                 HISTCONTROL
>   command_oriented_history        shopt cmdhist
>   glob_dot_filenames              shopt dotglob
>   allow_null_glob_expansion       shopt nullglob
>   nolinks                         set -o physical
>   hostname_completion_file        HOSTFILE
>   noclobber                       set -o noclobber
>   no_exitonfailed_exec            shopt execfail
>   cdable_vars                     shopt cdable_vars





reply via email to

[Prev in Thread] Current Thread [Next in Thread]