Thread: Patch to pg_ctl to better support paths containing spaces

Patch to pg_ctl to better support paths containing spaces

From
Barry Lind
Date:
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

Re: Patch to pg_ctl to better support paths containing

From
Peter Eisentraut
Date:
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


Re: Patch to pg_ctl to better support paths containing

From
Bruce Momjian
Date:
> 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

Re: Patch to pg_ctl to better support paths containing

From
Bruce Momjian
Date:
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

Re: Patch to pg_ctl to better support paths containing spaces

From
Bruce Momjian
Date:
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