Thread: Patch to pg_ctl to better support paths containing spaces
Attached is a set of changes to pg_ctl that I have been using that fixes problems I have had with pg_ctl when the paths contains spaces. thanks, --Barry *** ./bin/pg_ctl/pg_ctl.sh.orig Wed Sep 19 18:24:10 2001 --- ./bin/pg_ctl/pg_ctl.sh Wed Sep 19 21:08:49 2001 *************** *** 12,18 **** # #------------------------------------------------------------------------- ! CMDNAME=`basename $0` help="\ $CMDNAME is a utility to start, stop, restart, and report the status --- 12,18 ---- # #------------------------------------------------------------------------- ! CMDNAME=`basename "$0"` help="\ $CMDNAME is a utility to start, stop, restart, and report the status *************** *** 82,89 **** self_path=`echo "$0" | sed 's,/[^/]*$,,'` # (dirname command is not portable) else # look for it in PATH ('which' command is not portable) ! for dir in `echo "$PATH" | sed 's/:/ /g'` do # empty entry in path means current dir [ -z "$dir" ] && dir='.' if [ -f "$dir/$CMDNAME" ] --- 82,90 ---- self_path=`echo "$0" | sed 's,/[^/]*$,,'` # (dirname command is not portable) else # look for it in PATH ('which' command is not portable) ! for dir in `echo "$PATH" | sed 's/ /\\\_/g' | sed 's/:/ /g'` do + dir="`echo $dir | sed 's/\\\_/ /g'`" # empty entry in path means current dir [ -z "$dir" ] && dir='.' if [ -f "$dir/$CMDNAME" ] *************** *** 225,237 **** esac ! DEFPOSTOPTS=$PGDATA/postmaster.opts.default ! POSTOPTSFILE=$PGDATA/postmaster.opts ! PIDFILE=$PGDATA/postmaster.pid if [ "$op" = "status" ];then ! if [ -f $PIDFILE ];then ! PID=`sed -n 1p $PIDFILE` if [ $PID -lt 0 ];then PID=`expr 0 - $PID` echo "$CMDNAME: postgres is running (pid: $PID)" --- 226,238 ---- esac ! DEFPOSTOPTS="$PGDATA/postmaster.opts.default" ! POSTOPTSFILE="$PGDATA/postmaster.opts" ! PIDFILE="$PGDATA/postmaster.pid" if [ "$op" = "status" ];then ! if [ -f "$PIDFILE" ];then ! PID=`sed -n 1p "$PIDFILE"` if [ $PID -lt 0 ];then PID=`expr 0 - $PID` echo "$CMDNAME: postgres is running (pid: $PID)" *************** *** 248,255 **** fi if [ "$op" = "stop" -o "$op" = "restart" ];then ! if [ -f $PIDFILE ];then ! PID=`sed -n 1p $PIDFILE` if [ $PID -lt 0 ];then PID=`expr 0 - $PID` echo "$CMDNAME: Cannot restart postmaster. postgres is running (pid: $PID)" 1>&2 --- 249,256 ---- fi if [ "$op" = "stop" -o "$op" = "restart" ];then ! if [ -f "$PIDFILE" ];then ! PID=`sed -n 1p "$PIDFILE"` if [ $PID -lt 0 ];then PID=`expr 0 - $PID` echo "$CMDNAME: Cannot restart postmaster. postgres is running (pid: $PID)" 1>&2 *************** *** 266,272 **** while : do ! if [ -f $PIDFILE ];then $silence_echo $ECHO_N "."$ECHO_C cnt=`expr $cnt + 1` if [ $cnt -gt $wait_seconds ];then --- 267,273 ---- while : do ! if [ -f "$PIDFILE" ];then $silence_echo $ECHO_N "."$ECHO_C cnt=`expr $cnt + 1` if [ $cnt -gt $wait_seconds ];then *************** *** 283,289 **** fi $silence_echo echo "postmaster successfully shut down" ! else # ! -f $PIDFILE echo "$CMDNAME: cannot find $PIDFILE" 1>&2 echo "Is postmaster running?" 1>&2 if [ "$op" = "restart" ];then --- 284,290 ---- fi $silence_echo echo "postmaster successfully shut down" ! else # ! -f "$PIDFILE" echo "$CMDNAME: cannot find $PIDFILE" 1>&2 echo "Is postmaster running?" 1>&2 if [ "$op" = "restart" ];then *************** *** 296,316 **** if [ "$op" = "start" -o "$op" = "restart" ];then oldpid="" ! if [ -f $PIDFILE ];then echo "$CMDNAME: Another postmaster may be running. Trying to start postmaster anyway." 1>&2 ! oldpid=`sed -n 1p $PIDFILE` fi # no -o given if [ -z "$POSTOPTS" ];then if [ "$op" = "start" ];then # if we are in start mode, then look for postmaster.opts.default ! if [ -f $DEFPOSTOPTS ]; then ! eval set X "`cat $DEFPOSTOPTS`"; shift fi else # if we are in restart mode, then look for postmaster.opts ! eval set X "`cat $POSTOPTSFILE`"; shift po_path="$1" shift fi --- 297,317 ---- if [ "$op" = "start" -o "$op" = "restart" ];then oldpid="" ! if [ -f "$PIDFILE" ];then echo "$CMDNAME: Another postmaster may be running. Trying to start postmaster anyway." 1>&2 ! oldpid=`sed -n 1p "$PIDFILE"` fi # no -o given if [ -z "$POSTOPTS" ];then if [ "$op" = "start" ];then # if we are in start mode, then look for postmaster.opts.default ! if [ -f "$DEFPOSTOPTS" ]; then ! eval set X "`cat "$DEFPOSTOPTS"`"; shift fi else # if we are in restart mode, then look for postmaster.opts ! eval set X "`cat "$POSTOPTSFILE"`"; shift po_path="$1" shift fi *************** *** 319,325 **** fi if [ -n "$logfile" ]; then ! "$po_path" "$@" </dev/null >>$logfile 2>&1 & else # when starting without log file, redirect stderr to stdout, so # pg_ctl can be invoked with >$logfile and still have pg_ctl's --- 320,326 ---- fi if [ -n "$logfile" ]; then ! "$po_path" "$@" </dev/null >>"$logfile" 2>&1 & else # when starting without log file, redirect stderr to stdout, so # pg_ctl can be invoked with >$logfile and still have pg_ctl's *************** *** 330,337 **** # if had an old lockfile, check to see if we were able to start if [ -n "$oldpid" ];then sleep 1 ! if [ -f $PIDFILE ];then ! if [ "`sed -n 1p $PIDFILE`" = "$oldpid" ];then echo "$CMDNAME: cannot start postmaster" 1>&2 echo "Examine the log output." 1>&2 exit 1 --- 331,338 ---- # if had an old lockfile, check to see if we were able to start if [ -n "$oldpid" ];then sleep 1 ! if [ -f "$PIDFILE" ];then ! if [ "`sed -n 1p "$PIDFILE"`" = "$oldpid" ];then echo "$CMDNAME: cannot start postmaster" 1>&2 echo "Examine the log output." 1>&2 exit 1
Barry Lind writes: > Attached is a set of changes to pg_ctl that I have been using that fixes > problems I have had with pg_ctl when the paths contains spaces. > ! CMDNAME=`basename "$0"` OK. > else > # look for it in PATH ('which' command is not portable) > ! for dir in `echo "$PATH" | sed 's/ /\\\_/g' | sed 's/:/ /g'` > do > + dir="`echo $dir | sed 's/\\\_/ /g'`" > # empty entry in path means current dir > [ -z "$dir" ] && dir='.' Probably better to do this with IFS. Btw., this piece of code exists in identical form in most other PostgreSQL shell scripts. Do you intend to fix those as well? > ! DEFPOSTOPTS="$PGDATA/postmaster.opts.default" > ! POSTOPTSFILE="$PGDATA/postmaster.opts" > ! PIDFILE="$PGDATA/postmaster.pid" This is not necessary. > if [ "$op" = "status" ];then > ! if [ -f "$PIDFILE" ];then > ! PID=`sed -n 1p "$PIDFILE"` > if [ $PID -lt 0 ];then ... more similar stuff OK ... > else > # if we are in restart mode, then look for postmaster.opts > ! eval set X "`cat "$POSTOPTSFILE"`"; shift > po_path="$1" That is not portable. There is no portable way to have double quotes within backticks within double quotes. You might be able to do something along the lines of foo=`cat "$POSTOPTSFILE"` eval set X "$foo"; shift The expression in question was carefully engineered to handle single quotes and spaces in the POSTOPTSFILE correctly, so be careful. ;-) > if [ -n "$oldpid" ];then > sleep 1 > ! if [ -f "$PIDFILE" ];then > ! if [ "`sed -n 1p "$PIDFILE"`" = "$oldpid" ];then > echo "$CMDNAME: cannot start postmaster" 1>&2 > echo "Examine the log output." 1>&2 Same problem here. -- Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter
> Barry Lind writes: > > > Attached is a set of changes to pg_ctl that I have been using that fixes > > problems I have had with pg_ctl when the paths contains spaces. > > > ! CMDNAME=`basename "$0"` > > OK. I have made this change to all the scripts because everyone agrees with it. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Sorry, for some reason my email reader did not group these together. Removed from patch queue. > Barry Lind writes: > > > Attached is a set of changes to pg_ctl that I have been using that fixes > > problems I have had with pg_ctl when the paths contains spaces. > > > ! CMDNAME=`basename "$0"` > > OK. > > > else > > # look for it in PATH ('which' command is not portable) > > ! for dir in `echo "$PATH" | sed 's/ /\\\_/g' | sed 's/:/ /g'` > > do > > + dir="`echo $dir | sed 's/\\\_/ /g'`" > > # empty entry in path means current dir > > [ -z "$dir" ] && dir='.' > > Probably better to do this with IFS. Btw., this piece of code exists in > identical form in most other PostgreSQL shell scripts. Do you intend to > fix those as well? > > > ! DEFPOSTOPTS="$PGDATA/postmaster.opts.default" > > ! POSTOPTSFILE="$PGDATA/postmaster.opts" > > ! PIDFILE="$PGDATA/postmaster.pid" > > This is not necessary. > > > if [ "$op" = "status" ];then > > ! if [ -f "$PIDFILE" ];then > > ! PID=`sed -n 1p "$PIDFILE"` > > if [ $PID -lt 0 ];then > > ... more similar stuff OK ... > > > else > > # if we are in restart mode, then look for postmaster.opts > > ! eval set X "`cat "$POSTOPTSFILE"`"; shift > > po_path="$1" > > That is not portable. There is no portable way to have double quotes > within backticks within double quotes. You might be able to do something > along the lines of > > foo=`cat "$POSTOPTSFILE"` > eval set X "$foo"; shift > > The expression in question was carefully engineered to handle single > quotes and spaces in the POSTOPTSFILE correctly, so be careful. ;-) > > > if [ -n "$oldpid" ];then > > sleep 1 > > ! if [ -f "$PIDFILE" ];then > > ! if [ "`sed -n 1p "$PIDFILE"`" = "$oldpid" ];then > > echo "$CMDNAME: cannot start postmaster" 1>&2 > > echo "Examine the log output." 1>&2 > > Same problem here. > > -- > Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter > > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/users-lounge/docs/faq.html > -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026
This is very common. Almost any mention of an environment varible needs quoting. Of course, I will not ask why you have spaces in your paths. Your patch has been added to the PostgreSQL unapplied patches list at: http://candle.pha.pa.us/cgi-bin/pgpatches I will try to apply it within the next 48 hours. > Attached is a set of changes to pg_ctl that I have been using that fixes > problems I have had with pg_ctl when the paths contains spaces. > > thanks, > --Barry > *** ./bin/pg_ctl/pg_ctl.sh.orig Wed Sep 19 18:24:10 2001 > --- ./bin/pg_ctl/pg_ctl.sh Wed Sep 19 21:08:49 2001 > *************** > *** 12,18 **** > # > #------------------------------------------------------------------------- > > ! CMDNAME=`basename $0` > > help="\ > $CMDNAME is a utility to start, stop, restart, and report the status > --- 12,18 ---- > # > #------------------------------------------------------------------------- > > ! CMDNAME=`basename "$0"` > > help="\ > $CMDNAME is a utility to start, stop, restart, and report the status > *************** > *** 82,89 **** > self_path=`echo "$0" | sed 's,/[^/]*$,,'` # (dirname command is not portable) > else > # look for it in PATH ('which' command is not portable) > ! for dir in `echo "$PATH" | sed 's/:/ /g'` > do > # empty entry in path means current dir > [ -z "$dir" ] && dir='.' > if [ -f "$dir/$CMDNAME" ] > --- 82,90 ---- > self_path=`echo "$0" | sed 's,/[^/]*$,,'` # (dirname command is not portable) > else > # look for it in PATH ('which' command is not portable) > ! for dir in `echo "$PATH" | sed 's/ /\\\_/g' | sed 's/:/ /g'` > do > + dir="`echo $dir | sed 's/\\\_/ /g'`" > # empty entry in path means current dir > [ -z "$dir" ] && dir='.' > if [ -f "$dir/$CMDNAME" ] > *************** > *** 225,237 **** > esac > > > ! DEFPOSTOPTS=$PGDATA/postmaster.opts.default > ! POSTOPTSFILE=$PGDATA/postmaster.opts > ! PIDFILE=$PGDATA/postmaster.pid > > if [ "$op" = "status" ];then > ! if [ -f $PIDFILE ];then > ! PID=`sed -n 1p $PIDFILE` > if [ $PID -lt 0 ];then > PID=`expr 0 - $PID` > echo "$CMDNAME: postgres is running (pid: $PID)" > --- 226,238 ---- > esac > > > ! DEFPOSTOPTS="$PGDATA/postmaster.opts.default" > ! POSTOPTSFILE="$PGDATA/postmaster.opts" > ! PIDFILE="$PGDATA/postmaster.pid" > > if [ "$op" = "status" ];then > ! if [ -f "$PIDFILE" ];then > ! PID=`sed -n 1p "$PIDFILE"` > if [ $PID -lt 0 ];then > PID=`expr 0 - $PID` > echo "$CMDNAME: postgres is running (pid: $PID)" > *************** > *** 248,255 **** > fi > > if [ "$op" = "stop" -o "$op" = "restart" ];then > ! if [ -f $PIDFILE ];then > ! PID=`sed -n 1p $PIDFILE` > if [ $PID -lt 0 ];then > PID=`expr 0 - $PID` > echo "$CMDNAME: Cannot restart postmaster. postgres is running (pid: $PID)" 1>&2 > --- 249,256 ---- > fi > > if [ "$op" = "stop" -o "$op" = "restart" ];then > ! if [ -f "$PIDFILE" ];then > ! PID=`sed -n 1p "$PIDFILE"` > if [ $PID -lt 0 ];then > PID=`expr 0 - $PID` > echo "$CMDNAME: Cannot restart postmaster. postgres is running (pid: $PID)" 1>&2 > *************** > *** 266,272 **** > > while : > do > ! if [ -f $PIDFILE ];then > $silence_echo $ECHO_N "."$ECHO_C > cnt=`expr $cnt + 1` > if [ $cnt -gt $wait_seconds ];then > --- 267,273 ---- > > while : > do > ! if [ -f "$PIDFILE" ];then > $silence_echo $ECHO_N "."$ECHO_C > cnt=`expr $cnt + 1` > if [ $cnt -gt $wait_seconds ];then > *************** > *** 283,289 **** > fi > $silence_echo echo "postmaster successfully shut down" > > ! else # ! -f $PIDFILE > echo "$CMDNAME: cannot find $PIDFILE" 1>&2 > echo "Is postmaster running?" 1>&2 > if [ "$op" = "restart" ];then > --- 284,290 ---- > fi > $silence_echo echo "postmaster successfully shut down" > > ! else # ! -f "$PIDFILE" > echo "$CMDNAME: cannot find $PIDFILE" 1>&2 > echo "Is postmaster running?" 1>&2 > if [ "$op" = "restart" ];then > *************** > *** 296,316 **** > > if [ "$op" = "start" -o "$op" = "restart" ];then > oldpid="" > ! if [ -f $PIDFILE ];then > echo "$CMDNAME: Another postmaster may be running. Trying to start postmaster anyway." 1>&2 > ! oldpid=`sed -n 1p $PIDFILE` > fi > > # no -o given > if [ -z "$POSTOPTS" ];then > if [ "$op" = "start" ];then > # if we are in start mode, then look for postmaster.opts.default > ! if [ -f $DEFPOSTOPTS ]; then > ! eval set X "`cat $DEFPOSTOPTS`"; shift > fi > else > # if we are in restart mode, then look for postmaster.opts > ! eval set X "`cat $POSTOPTSFILE`"; shift > po_path="$1" > shift > fi > --- 297,317 ---- > > if [ "$op" = "start" -o "$op" = "restart" ];then > oldpid="" > ! if [ -f "$PIDFILE" ];then > echo "$CMDNAME: Another postmaster may be running. Trying to start postmaster anyway." 1>&2 > ! oldpid=`sed -n 1p "$PIDFILE"` > fi > > # no -o given > if [ -z "$POSTOPTS" ];then > if [ "$op" = "start" ];then > # if we are in start mode, then look for postmaster.opts.default > ! if [ -f "$DEFPOSTOPTS" ]; then > ! eval set X "`cat "$DEFPOSTOPTS"`"; shift > fi > else > # if we are in restart mode, then look for postmaster.opts > ! eval set X "`cat "$POSTOPTSFILE"`"; shift > po_path="$1" > shift > fi > *************** > *** 319,325 **** > fi > > if [ -n "$logfile" ]; then > ! "$po_path" "$@" </dev/null >>$logfile 2>&1 & > else > # when starting without log file, redirect stderr to stdout, so > # pg_ctl can be invoked with >$logfile and still have pg_ctl's > --- 320,326 ---- > fi > > if [ -n "$logfile" ]; then > ! "$po_path" "$@" </dev/null >>"$logfile" 2>&1 & > else > # when starting without log file, redirect stderr to stdout, so > # pg_ctl can be invoked with >$logfile and still have pg_ctl's > *************** > *** 330,337 **** > # if had an old lockfile, check to see if we were able to start > if [ -n "$oldpid" ];then > sleep 1 > ! if [ -f $PIDFILE ];then > ! if [ "`sed -n 1p $PIDFILE`" = "$oldpid" ];then > echo "$CMDNAME: cannot start postmaster" 1>&2 > echo "Examine the log output." 1>&2 > exit 1 > --- 331,338 ---- > # if had an old lockfile, check to see if we were able to start > if [ -n "$oldpid" ];then > sleep 1 > ! if [ -f "$PIDFILE" ];then > ! if [ "`sed -n 1p "$PIDFILE"`" = "$oldpid" ];then > echo "$CMDNAME: cannot start postmaster" 1>&2 > echo "Examine the log output." 1>&2 > exit 1 > > ---------------------------(end of broadcast)--------------------------- > TIP 2: you can get off all lists at once with the unregister command > (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026