building strings with variable input

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Olaf Meyer

    building strings with variable input

    Sometimes if find it clumsy unsing the following approach building strings:

    cmd = "%s -start %s -end %s -dir %s" % (executable, startTime, endTime,
    directory)

    Especially if you have a lot of variable input it makes it hard to match
    the variables to the proper fields. From other scripting languanges I'm
    used to something like:

    $cmd = "$executabl e -start $startTime -end $endTime -dir $directory"

    This makes it very easy to see how the string is actually built. You
    dont't have to worry where which variables go.

    Is there a similar way to do this in python?

    Thanks,
    Olaf
  • Erik Max Francis

    #2
    Re: building strings with variable input

    Olaf Meyer wrote:
    [color=blue]
    > Especially if you have a lot of variable input it makes it hard to
    > match
    > the variables to the proper fields. From other scripting languanges
    > I'm
    > used to something like:
    >
    > $cmd = "$executabl e -start $startTime -end $endTime -dir $directory"
    >
    > This makes it very easy to see how the string is actually built. You
    > dont't have to worry where which variables go.
    >
    > Is there a similar way to do this in python?[/color]

    Sure:

    cmd = "%(executab le)s -start %(startTime)s -end %(endTime)s -dir
    %(directory)s" % locals()

    There are also more expansive solutions such as YAPTU or EmPy.

    Note, however, that what you are trying to do (presuming you're passing
    this to os.system or something similar) is potentially a serious
    security risk. If the values of the strings you are constructing the
    command line are not fully trustworthy, they can be easily manipulated
    to make your program execute arbitrary shell commands.

    --
    __ Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
    / \ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    \__/ In the fight between you and the world, back the world.
    -- Frank Zappa

    Comment

    • Peter Otten

      #3
      Re: building strings with variable input

      Olaf Meyer wrote:
      [color=blue]
      > Sometimes if find it clumsy unsing the following approach building
      > strings:
      >
      > cmd = "%s -start %s -end %s -dir %s" % (executable, startTime, endTime,
      > directory)
      >
      > Especially if you have a lot of variable input it makes it hard to match
      > the variables to the proper fields. From other scripting languanges I'm
      > used to something like:
      >
      > $cmd = "$executabl e -start $startTime -end $endTime -dir $directory"
      >
      > This makes it very easy to see how the string is actually built. You
      > dont't have to worry where which variables go.
      >
      > Is there a similar way to do this in python?[/color]
      [color=blue][color=green][color=darkred]
      >>> "from %(org)s to %(dest)s" % dict(org="X", dest="Y")[/color][/color][/color]
      'from X to Y'

      or even
      [color=blue][color=green][color=darkred]
      >>> org = "A"
      >>> dest = "B"
      >>> "from %(org)s to %(dest)s" % locals()[/color][/color][/color]
      'from A to B'

      Peter

      Comment

      • Olaf Meyer

        #4
        Re: building strings with variable input

        Erik Max Francis wrote:
        [color=blue]
        > Olaf Meyer wrote:
        >
        >[color=green]
        >>Especially if you have a lot of variable input it makes it hard to
        >>match
        >>the variables to the proper fields. From other scripting languanges
        >>I'm
        >>used to something like:
        >>
        >> $cmd = "$executabl e -start $startTime -end $endTime -dir $directory"
        >>
        >>This makes it very easy to see how the string is actually built. You
        >>dont't have to worry where which variables go.
        >>
        >>Is there a similar way to do this in python?[/color]
        >
        >
        > Sure:
        >
        > cmd = "%(executab le)s -start %(startTime)s -end %(endTime)s -dir
        > %(directory)s" % locals()
        >
        > There are also more expansive solutions such as YAPTU or EmPy.
        >
        > Note, however, that what you are trying to do (presuming you're passing
        > this to os.system or something similar) is potentially a serious
        > security risk. If the values of the strings you are constructing the
        > command line are not fully trustworthy, they can be easily manipulated
        > to make your program execute arbitrary shell commands.
        >[/color]

        Erik,

        thanks for your solution suggestion and pointing out the security risks.
        However security is not an issue in my case ;-)

        Olaf

        Comment

        • David M. Cooke

          #5
          Re: building strings with variable input

          At some point, Erik Max Francis <max@alcyone.co m> wrote:
          [color=blue]
          > Olaf Meyer wrote:
          >[color=green]
          >> Especially if you have a lot of variable input it makes it hard to
          >> match
          >> the variables to the proper fields. From other scripting languanges
          >> I'm
          >> used to something like:
          >>
          >> $cmd = "$executabl e -start $startTime -end $endTime -dir $directory"
          >>
          >> This makes it very easy to see how the string is actually built. You
          >> dont't have to worry where which variables go.
          >>
          >> Is there a similar way to do this in python?[/color]
          >
          > Sure:
          >
          > cmd = "%(executab le)s -start %(startTime)s -end %(endTime)s -dir
          > %(directory)s" % locals()
          >
          > There are also more expansive solutions such as YAPTU or EmPy.
          >
          > Note, however, that what you are trying to do (presuming you're passing
          > this to os.system or something similar) is potentially a serious
          > security risk. If the values of the strings you are constructing the
          > command line are not fully trustworthy, they can be easily manipulated
          > to make your program execute arbitrary shell commands.[/color]

          In which case he's probably better off with his original format (almost):

          cmd = '"$executabl e" -start "$startTime " -end "$endTime" -dir "$directory "'
          os.environ['executable'] = 'blah'
          os.environ['startTime'] = '12'
          os.environ['endTime'] = '18'
          os.environ['directory'] = './'
          os.system(cmd)

          This way, the shell handles all the quoting. You can do
          del os.environ['executable']
          afterwards to clean up. I got this technique from
          Compare the best free open source Software Development Software at SourceForge. Free, secure and fast Software Development Software downloads from the largest Open Source applications and software directory


          For the quoting, compare:[color=blue][color=green][color=darkred]
          >>> os.environ['string'] = "`uname` $TERM"
          >>> os.system('echo "$string"')[/color][/color][/color]
          `uname` $PATH
          (this is what we want: don't run arbitrary commands or expand
          environment variables given in a user string)

          with[color=blue][color=green][color=darkred]
          >>> string = "`uname` $TERM"
          >>> os.system('echo "%s"' % string)[/color][/color][/color]
          Linux xterm
          (whoops, security leak)

          --
          |>|\/|<
          /--------------------------------------------------------------------------\
          |David M. Cooke
          |cookedm(at)phy sics(dot)mcmast er(dot)ca

          Comment

          • Olaf Meyer

            #6
            Re: building strings with variable input

            Erik Max Francis wrote:
            [color=blue]
            > Olaf Meyer wrote:
            >
            >[color=green]
            >>Especially if you have a lot of variable input it makes it hard to
            >>match
            >>the variables to the proper fields. From other scripting languanges
            >>I'm
            >>used to something like:
            >>
            >> $cmd = "$executabl e -start $startTime -end $endTime -dir $directory"
            >>
            >>This makes it very easy to see how the string is actually built. You
            >>dont't have to worry where which variables go.
            >>
            >>Is there a similar way to do this in python?[/color]
            >
            >
            > Sure:
            >
            > cmd = "%(executab le)s -start %(startTime)s -end %(endTime)s -dir
            > %(directory)s" % locals()
            >
            > There are also more expansive solutions such as YAPTU or EmPy.
            >
            > Note, however, that what you are trying to do (presuming you're passing
            > this to os.system or something similar) is potentially a serious
            > security risk. If the values of the strings you are constructing the
            > command line are not fully trustworthy, they can be easily manipulated
            > to make your program execute arbitrary shell commands.
            >[/color]

            I just found out another way ;-) Using the locals() has the disadvantage
            that I cannot use more complex variable parameters (e.g. certain values
            of a dictionary). The following works well:

            cmd = (executable + " -start " + startTime + " -end " + endTime +
            " -dir " + options.dir)

            Olaf

            Comment

            • Erik Max Francis

              #7
              Re: building strings with variable input

              "David M. Cooke" wrote:
              [color=blue]
              > In which case he's probably better off with his original format
              > (almost):
              >
              > cmd = '"$executabl e" -start "$startTime " -end "$endTime" -dir \
              > "$directory "'
              > os.environ['executable'] = 'blah'
              > os.environ['startTime'] = '12'
              > os.environ['endTime'] = '18'
              > os.environ['directory'] = './'
              > os.system(cmd)[/color]

              This doesn't resolve the underlying possibility for mailicious people in
              control of the contents of those variables to get it to execute
              arbitrary shell code. (In his case he says it isn't an issue, but
              still.)

              --
              __ Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
              / \ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
              \__/ It was involuntary. They sank my boat.
              -- John F. Kennedy (on how he became a war hero)

              Comment

              • Paul McGuire

                #8
                Re: building strings with variable input

                "Tim Roberts" <timr@probo.com > wrote in message
                news:3rr900dm9s 7th7kgq4muj76d5 ocs5uep3b@4ax.c om...[color=blue]
                > Olaf Meyer <nomail@nospam. net> wrote:[color=green]
                > >
                > >I just found out another way ;-) Using the locals() has the disadvantage
                > >that I cannot use more complex variable parameters (e.g. certain values
                > >of a dictionary). The following works well:
                > >
                > >cmd = (executable + " -start " + startTime + " -end " + endTime +
                > > " -dir " + options.dir)[/color]
                >
                > Yes, that works, but you should bear in mind that it is slower than the %s
                > option. The "+" operations are all separate interpreter steps, while the
                > "%" operation is done in C.
                >[/color]

                On the relative time scales of concatenating 7 strings compared to forking
                off a separate process (which I presume is what is to be done with cmd), I'd
                go for the more readable representation, to aid in long term
                maintainability .

                If I have some string concatenation being done in a highly repetitive part
                of code, then by all means, replace it with one of the half dozen documented
                optimized alternatives. But if I build a string in order to create a
                sub-process, or invoke a database query, or make a remote CORBA invocation,
                etc., then these "optimizati ons" don't really save much time, and instead
                distract me/reviewers/testers/maintainers from the important program logic.

                -- Paul


                Comment

                • Dave Benjamin

                  #9
                  Re: building strings with variable input

                  In article <pduMb.6321$g4. 137247@news2.no kia.com>, Olaf Meyer wrote:[color=blue]
                  > Sometimes if find it clumsy unsing the following approach building strings:
                  >
                  > cmd = "%s -start %s -end %s -dir %s" % (executable, startTime, endTime,
                  > directory)
                  >
                  > Especially if you have a lot of variable input it makes it hard to match
                  > the variables to the proper fields. From other scripting languanges I'm
                  > used to something like:
                  >
                  > $cmd = "$executabl e -start $startTime -end $endTime -dir $directory"
                  >
                  > This makes it very easy to see how the string is actually built. You
                  > dont't have to worry where which variables go.
                  >
                  > Is there a similar way to do this in python?[/color]

                  Go here:


                  Look under "string interpolation for Python".

                  Examples supported:

                  "Here is a $string."
                  "Here is a $module.member. "
                  "Here is an $object.member. "
                  "Here is a $functioncall(w ith, arguments)."
                  "Here is an ${arbitrary + expression}."
                  "Here is an $array[3] member."
                  "Here is a $dictionary['member']."

                  Thanks to Ka-Ping Yee! I've succesfully used this to build a homebrew
                  templating language. It's nice and lightweight.

                  --
                  ..:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
                  : d r i n k i n g l i f e o u t o f t h e c o n t a i n e r :

                  Comment

                  Working...