In init.d scripts, it used to be that 'exit 1' and 'return 1' in one of the main functions had the same behavior of causing a proper failure. There are a LOT of scripts that use 'exit 1' as such. Since later daemons then think something previous has started correctly, they start and also fail. However, sometime recently, 'exit 1' ceased to work properly, as evidenced by the demonstration below. I've tested two versions of baselayout, and found this holds for both of them: 1.11.10-r2 1.11.9-r1 Reproducible: Always Steps to Reproduce: /etc/init.d/rc-testscript: ---- #!/sbin/runscript start() { exit 1 } ---- # /etc/init.d/rc-testscript start ; echo $? 1 # /etc/init.d/rc-testscript start ; echo $? * WARNING: "rc-testscript" has already been started. 0 # rc-status | grep rc-testscript (no output) # find /var/lib/init.d/ |grep rc-testscript /var/lib/init.d/started/rc-testscript Portage 2.0.51.19 (default-linux/x86/2004.2, gcc-3.4.3, glibc-2.3.4.20050125- r0, 2.6.10-gentoo-r4 i686) ================================================================= System uname: 2.6.10-gentoo-r4 i686 AMD Athlon(tm) XP 3000+ Gentoo Base System version 1.6.10 Python: dev-lang/python-2.3.5 [2.3.5 (#1, Feb 20 2005, 02:21:17)] distcc 2.18.3 i686-pc-linux-gnu (protocols 1 and 2) (default port 3632) [disabled] ccache version 2.3 [enabled] dev-lang/python: 2.3.5 sys-devel/autoconf: 2.59-r6, 2.13 sys-devel/automake: 1.7.9-r1, 1.8.5-r3, 1.5, 1.4_p6, 1.6.3, 1.9.4 sys-devel/binutils: 2.15.92.0.2-r2 sys-devel/libtool: 1.5.10-r4 virtual/os-headers: 2.6.8.1-r2 ACCEPT_KEYWORDS="x86 ~x86" ACCEPT_LICENSE="" ARCH="x86" AUTOCLEAN="yes" BASH_ENV="/etc/spork/is/not/valid/profile.env" CCACHE_DIR="/var/tmp/ccache" CCACHE_SIZE="2G" CFLAGS="-O3 -march=athlon-xp -fomit-frame-pointer -pipe" CHOST="i686-pc-linux-gnu" CLASSPATH="." CLEAN_DELAY="5" CONFIG_PROTECT="/etc /usr/kde/2/share/config /usr/kde/3.3/env /usr/kde/3.3/share /config /usr/kde/3.3/shutdown /usr/kde/3/share/config /usr/lib/X11/xkb /usr/lib/ mozilla/defaults/pref /usr/share/config /usr/share/texmf/dvipdfm/config/ /usr/sh are/texmf/dvips/config/ /usr/share/texmf/tex/generic/config/ /usr/share/texmf/te x/platex/config/ /usr/share/texmf/xdvi/ /var/qmail/control" CONFIG_PROTECT_MASK="/etc/gconf /etc/terminfo /etc/env.d" CVS_RSH="ssh" CXXFLAGS="-O3 -march=athlon-xp -fomit-frame-pointer -pipe" DCCC_PATH="/usr/lib/distcc/bin" DISTCC_DIR="/dev/shm/.distcc" DISTCC_LOG="" DISTCC_VERBOSE="0" DISTDIR="/usr/portage-distfiles" ECHANGELOG_USER="Robin H. Johnson <robbat2@gentoo.org>" EDITOR="/usr/bin/vim" FEATURES="autoaddcvs autoconfig buildpkg ccache confcache cvs digest distlocks sandbox sfperms userpriv" FETCHCOMMAND="/usr/bin/wget -t 5 --passive-ftp -P ${DISTDIR} ${URI}" GCC_SPECS="" GDK_USE_XFT="1" GENTOO_MIRRORS="http://distfiles.gentoo.org http://distro.ibiblio.org/pub/Linux/distributions/gentoo" GLIBC_SSP_CHECKED="1" GRP_STAGE23_USE="ipv6 pam tcpd readline nls ssl gpm perl python berkdb acl ncurses" GUILE_LOAD_PATH="/usr/share/guile/1.6" G_BROKEN_FILENAMES="1" HOME="/root" HOSTNAME="x29" INFOPATH="/usr/share/info:/usr/share/binutils-data/i686-pc-linux- gnu/2.15.92.0.2/info:/usr/share/gcc-data/i686-pc-linux-gnu/3.4.3/info" JAVAC="/opt/blackdown-jdk-1.4.2.01/bin/javac" JAVA_HOME="/opt/blackdown-jdk-1.4.2.01" JDK_HOME="/opt/blackdown-jdk-1.4.2.01" KDEDIRS="/usr" KDE_MALLOC="1" LESS="-R" LESSOPEN="|lesspipe.sh %s" LINGUAS="en" LOGNAME="root" LS_COLORS="no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01: cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com =01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*. arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.b z2=01;31:*.bz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.rar=01;31: *.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01 ;35:*.gif=01;35:*.bmp=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.ti f=01;35:*.tiff=01;35:*.png=01;35:*.mng=01;35:*.xcf=01;35:*.pcx=01;35:*.mpg=01;35 :*.mpeg=01;35:*.m2v=01;35:*.avi=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v= 01;35:*.mp4v=01;35:*.mov=01;35:*.qt=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.r mvb=01;35:*.flc=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.pdf=00;32:*.ps=00;32:* .txt=00;32:*.patch=00;32:*.diff=00;32:*.log=00;32:*.tex=00;32:*.doc=00;32:*.mp3= 00;36:*.wav=00;36:*.mid=00;36:*.midi=00;36:*.au=00;36:*.ogg=00;36:*.flac=00;36:* .aac=00;36:" MAIL="/var/mail/root" MAKEOPTS="-j1" MANPATH="/usr/local/share/man:/usr/share/man:/usr/share/binutils-data/i686-pc- linux-gnu/2.15.92.0.2/man:/usr/share/gcc-data/i686-pc-linux- gnu/3.4.3/man::/opt/blackdown-jdk-1.4.2.01/man:/usr/qt/3/doc/man" MOZILLA_FIVE_HOME="/usr/lib/mozilla" NOCOLOR="false" OLDPWD="/usr/portage/sys-apps" PAGER="/usr/bin/less" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/usr /i686-pc-linux-gnu/gcc-bin/3.4.3:/opt/blackdown-jdk-1.4.2.01/bin:/opt/blackdown- jdk- 1.4.2.01/jre/bin:/usr/qt/3/bin:/usr/kde/3.3/sbin:/usr/kde/3.3/bin:/usr/share/kar amba/bin" PKGDIR="/usr/portage-packages" PORTAGE_ARCHLIST="alpha amd64 arm hppa ia64 m68k mips ppc ppc64 ppc-macos ppc- od s390 sh sparc x86 x86-fbsd x86-obsd x86-od" PORTAGE_BINHOST_CHUNKSIZE="3000" PORTAGE_CALLER="emerge" PORTAGE_GID="250" PORTAGE_MASTER_PID="14380" PORTAGE_NICENESS="3" PORTAGE_TMPDIR="/dev/shm" PORTDIR="/usr/portage" PORTDIR_OVERLAY="/usr/local/portage" PORT_LOGDIR="/var/log/portage" PRELINK_PATH="" PRELINK_PATH_MASK="/usr/lib/wine:/usr/lib/valgrind" PWD="/usr/portage" QMAKESPEC="linux-g++" QTDIR="/usr/qt/3" REMOTEHOST="home" RESUMECOMMAND="/usr/bin/wget -c -t 5 --passive-ftp -P ${DISTDIR} ${URI}" RPMDIR="/usr/portage/rpm" RSYNC_RETRIES="3" RSYNC_TIMEOUT="180" SANE_CONFIG_DIR="/etc/sane.d" SGML_CATALOG_FILES="/etc/sgml/sgml-docbook.cat:/etc/sgml/openjade- 1.3.2.cat:/etc/sgml/sgml-ent.cat:/etc/sgml/xml-simple-docbook- 4.1.2.4.cat:/etc/sgml/sgml-docbook-3.0.cat:/etc/sgml/sgml-docbook- 3.1.cat:/etc/sgml/sgml-docbook-4.0.cat:/etc/sgml/sgml-docbook- 4.1.cat:/etc/sgml/sgml-lite.cat:/etc/sgml/dsssl-docbook-stylesheets.cat" SHELL="/bin/bash" SHLVL="1" SSH_AUTH_SOCK="/tmp/ssh-odeAqu3968/agent.3968" SSH_CLIENT="24.80.100.253 3084 22" SSH_CONNECTION="24.80.100.253 3084 209.87.56.114 22" SSH_TTY="/dev/pts/2" SYNC="rsync://yamato/gentoo-portage" TERM="xterm" USE="x86 3dnow X Xaw3d aalib acl acpi alsa amd apache2 apm arts avi berkdb bitmap-fonts caps cdr cgi clearpasswd crypt cscope cups curl divx4linux dri dts dvd dvdr emboss encode erandom escreen esd ethereal expat f77 faac faad fam flac flash foomaticdb fortran gcj gd gdbm gif glx gnome gpm gstreamer imagemagick imap imlib innodb ipalias ipv6 jabber jack java javascript jikes jpeg junit kde ldap libwww mad maildir mcal md5sum mikmod mmx motif mozcalendar mozdevelop mozsvg mozxmlterm mp3 mpeg multitarget nas ncurses nls nptl oav objc offensive oggvorbis opengl pam pcap pda pdflib perl pic plotutils png pnp ppds python quicktime readline rpc samba scanner sdl slang slp snmp socks5 speex spell sqlite sse ssl tcltk tcpd tetex theora tiff truetype truetype-fonts type1 type1-fonts ungif usb userlocales v4l v4l2 wifi wmf wxwindows xinerama xml xml2 xmms xosd xrandr xv xvid zlib linguas_en" USER="root" USERLAND="GNU" USE_EXPAND="VIDEO_CARDS INPUT_DEVICES LINGUAS" XARGS="xargs -r" XINITRC="/etc/X11/xinit/xinitrc" XSESSION="fluxbox" _="/usr/bin/emerge"
i doubt this behavior change is recent considering this changed over a year and a half ago: http://www.gentoo.org/cgi-bin/viewcvs.cgi/rc-scripts/sbin/runscript.sh?root=gentoo-src&r1=1.28&r2=1.29 really i say we make people do 'return' instead of 'exit' ... how about this: elif [[ ${retval} -eq 0 ]] && ! broken "${myservice}" ; then ( exit() { eerror "DONT USE exit() IN INIT.D SCRIPTS" ; exit $@ ; } start )
vapier: nice infinite loop there.
true point still stands though, i dont think we should support exit() in init.d scripts
there is one problem with that however. for init scripts where the init.d scripts calls an external shell script, that case is not correct (as exit in itself is a valid shell call).
true enough i say we leave current behavior as is and make people fix their init.d scripts
I'm reopening this until we've made it very clear to the devs that they should be using 'return' instead of 'exit'. I'll see about running some checks on the tree as well
vapier's example really just needed one fix. seems like this would be a good stop-gap. exit() { eerror "DONT USE exit() IN INIT.D SCRIPTS" ; command exit "$@"; } another possibility would be to do shopt -s expand_aliases alias exit=return and it would be transparent. IMHO either of these might be better than mass education of devs regarding something trivial that isn't ever going to be done right.
agriffis: defining exit to a function that spits a warning will still screw up cases where the init.d calls an external shell script, and that script wants to call exit. I don't know if the alias route safe in that case either.
i'd vote for the warning rather than the transparent alias ... i like when our code yells at devs for doing the wrong thing :)
robbat2: i'm pretty sure not consider this example: $ cat init.d #!/bin/bash -x exit() { echo "eat it" ; } start() { ./myscript } start echo FIN exit 1 $ cat myscript #!/bin/bash exit 0 $ ./init.d + start + ./myscript + echo FIN FIN + exit 1 + echo 'eat it' eat it
ive added this to baselayout-1.11.12: ( exit() { eerror "DO NOT USE EXIT IN INIT.D SCRIPTS" eerror "this IS a bug, please fix your init.d script" unset exit exit $@ } start )