system(@args) query, result not as expected.

Discussion in 'Perl Misc' started by Justin C, Mar 4, 2009.

  1. Justin C

    Justin C Guest

    I have the following:

    my @args = ("mount", "-t smbfs -o username=boris,password=drowssap",
    "\"//255.255.255.255/Some Share with spaces\"", "/mnt/foo");

    The error is *nix, not perl, but, please bear with me and read on. Here
    is the error:

    mount: unknown filesystem type 'password=drowssap"'

    I chaned @args to be one string only:

    my @args = ("mount -t smbfs -o username=boris,password=drowssap \"//255.255.255.255/Some Share with spaces\" /mnt/foo");

    And it all works just fine. I thought that maybe @args weren't being
    presented in order so a line just prior to 'system' I did a print, all
    looked OK.

    Any ideas why the mount command was thinking that 'password' was the
    filesystem type?

    Justin.

    --
    Justin C, by the sea.
     
    Justin C, Mar 4, 2009
    #1
    1. Advertising

  2. Justin C wrote:
    > I have the following:
    >
    > my @args = ("mount", "-t smbfs -o username=boris,password=drowssap",
    > "\"//255.255.255.255/Some Share with spaces\"", "/mnt/foo");
    >
    > The error is *nix, not perl, but, please bear with me and read on. Here
    > is the error:
    >
    > mount: unknown filesystem type 'password=drowssap"'
    >
    > I chaned @args to be one string only:
    >
    > my @args = ("mount -t smbfs -o username=boris,password=drowssap \"//255.255.255.255/Some Share with spaces\" /mnt/foo");
    >
    > And it all works just fine. I thought that maybe @args weren't being
    > presented in order so a line just prior to 'system' I did a print, all
    > looked OK.
    >
    > Any ideas why the mount command was thinking that 'password' was the
    > filesystem type?


    Because it's in the same argument to "mount" as the "-t"-option:

    "More than one type may be specified in a comma separated list."
    (man mount).

    I.e. "mount" thinks that you passed the following to specify the vfstype:

    "-t smbfs -o username=boris,password=drowssap"

    which it parses as two vfstypes:
    " smbfs -o username=boris" and "password=drowssap".

    I haven't looked into the source of "mount", but maybe "mount" tries the
    first, which fails, tries the second, which also fails, and then issues
    an error message for the second only.

    Try putting each argument into a separate string:

    my @args = ("mount", "-t", "smbfs", "-o",
    "username=boris,password=drowssap",
    "\"//255.255.255.255/Some Share with spaces\"", "/mnt/foo");

    Josef
    --
    These are my personal views and not those of Fujitsu Siemens Computers!
    Josef Möllers (Pinguinpfleger bei FSC)
    If failure had no penalty success would not be a prize (T. Pratchett)
    Company Details: http://www.fujitsu-siemens.com/imprint.html
     
    Josef Moellers, Mar 4, 2009
    #2
    1. Advertising

  3. Justin C <> wrote:
    >
    > I have the following:
    >
    > my @args = ("mount", "-t smbfs -o username=boris,password=drowssap",
    > "\"//255.255.255.255/Some Share with spaces\"", "/mnt/foo");
    >
    > The error is *nix, not perl, but, please bear with me and read on. Here
    > is the error:
    >
    > mount: unknown filesystem type 'password=drowssap"'
    >
    > I chaned @args to be one string only:
    >
    > my @args = ("mount -t smbfs -o username=boris,password=drowssap \"//255.255.255.255/Some Share with spaces\" /mnt/foo");
    >
    > And it all works just fine. I thought that maybe @args weren't being
    > presented in order so a line just prior to 'system' I did a print, all
    > looked OK.
    >
    > Any ideas why the mount command was thinking that 'password' was the
    > filesystem type?



    The 2nd sentence of the docs for the function you are using
    explains it:

    perldoc -f system

    ...
    Note that argument processing varies depending on the
    number of arguments...

    You want mount's 1st arg to be "-t" and its 2nd arg to be "smbfs" etc,
    but you have given this 1st arg instead:

    -t smbfs -o username=boris,password=drowssap

    Also, you want one of the args to be

    //255.255.255.255/Some Share with spaces

    but have given it

    "//255.255.255.255/Some Share with spaces"

    instead.

    When you are using system() with many args, there is no shell involved.

    When there is no shell, there is no need to protect spaces from the
    shell's argument processing, so you don't need or want the double quotes.



    You need to make each argument a separate element in the array:

    my @args = (
    'mount',
    '-t',
    'smbfs',
    '-o',
    'username=boris,password=drowssap',
    '//255.255.255.255/Some Share with spaces',
    '/mnt/foo',
    );


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
     
    Tad J McClellan, Mar 4, 2009
    #3
  4. It happens because Perl starts $args[0] with arguments $args[1], $args
    [2], ... as if in single quotes which disables shell's mechanism to
    evaluate and tokenize the string. Single quoting preserves everything,
    including spaces, and this is what happens:

    Listing: 1.pl
    =============

    #!/usr/bin/perl

    use warnings;
    use strict;

    my @args = ("ls","-l /tmp");
    eval {
    system(@args);
    };
    if ($@) {
    print "Error: $@\n";
    }

    Output:
    =======

    ls: invalid option --
    Try `ls --help' for more information.

    Now see how this is equivalent to the following at command prompt:

    [bld@BLD-RHEL5-32 perl_progs]# 'ls' '-l /tmp'
    ls: invalid option --
    Try `ls --help' for more information.

    And see this:

    [bld@BLD-RHEL5-32 perl_progs]# 'ls' '-l' '/tmp'
    total 8
    drwxr-xr-x 2 root root 4096 Mar 4 07:05 chumma
    -rw-r--r-- 1 root root 3 Feb 27 15:20 TEST

    The last example above works because even though they are single-
    quoted, there are no preserved spaces (which are basically the cause
    of the problem here). So, like, Josef said, pass each argument on its
    own and don't include any spaces in quotes. Or, like you figured out,
    pass everything as a single string, which will be checked for shell
    metacharacters and will be invoked as /bin/sh -c <command>.

    -Chaitanya
     
    Krishna Chaitanya, Mar 4, 2009
    #4
  5. Chris Mattern wrote:
    > On 2009-03-04, Justin C <> wrote:
    >> I have the following:
    >>
    >> my @args = ("mount", "-t smbfs -o username=boris,password=drowssap",
    >> "\"//255.255.255.255/Some Share with spaces\"", "/mnt/foo");
    >>
    >> The error is *nix, not perl, but, please bear with me and read on. Here
    >> is the error:
    >>
    >> mount: unknown filesystem type 'password=drowssap"'
    >>
    >> I chaned @args to be one string only:
    >>
    >> my @args = ("mount -t smbfs -o username=boris,password=drowssap \"//255.255.255.255/Some Share with spaces\" /mnt/foo");
    >>
    >> And it all works just fine. I thought that maybe @args weren't being
    >> presented in order so a line just prior to 'system' I did a print, all
    >> looked OK.
    >>
    >> Any ideas why the mount command was thinking that 'password' was the
    >> filesystem type?

    >
    > Because you conflated the -o argument with the -t argument by making them
    > all one argument. Try this:
    >
    > my @args = ("mount", "-t smbfs", "-o username=boris,password=drowssap",
    > "\"//255.255.255.255/Some Share with spaces\"", "/mnt/foo");


    This is only half-way and won't work:

    "mount: unknown filesystem type ' smbfs'" (note the blank before "smbfs").

    Josef
    --
    These are my personal views and not those of Fujitsu Siemens Computers!
    Josef Möllers (Pinguinpfleger bei FSC)
    If failure had no penalty success would not be a prize (T. Pratchett)
    Company Details: http://www.fujitsu-siemens.com/imprint.html
     
    Josef Moellers, Mar 4, 2009
    #5
  6. >
    > This is only half-way and won't work:
    >
    > "mount: unknown filesystem type ' smbfs'" (note the blank before "smbfs").


    That's because of what I had said above, I guess.....any space present
    in the list items will be preserved verbatim at the program invocation
    time.
     
    Krishna Chaitanya, Mar 4, 2009
    #6
  7. Justin C

    Justin C Guest

    On 2009-03-04, Justin C <> wrote:
    >
    > I have the following:
    >
    > my @args = ("mount", "-t smbfs -o username=boris,password=drowssap",
    > "\"//255.255.255.255/Some Share with spaces\"", "/mnt/foo");


    [snip]

    Thank you all, very clear and concise. I have a better understanding of
    the command now and shall implement it correctly.... and have, and all
    is good.

    Thank all, again, for your regular help.

    Justin.

    --
    Justin C, by the sea.
     
    Justin C, Mar 4, 2009
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ken Varn
    Replies:
    2
    Views:
    657
    Ken Varn
    Jun 22, 2005
  2. Replies:
    3
    Views:
    536
    David Eppstein
    Sep 17, 2003
  3. Pierre Fortin

    args v. *args passed to: os.path.join()

    Pierre Fortin, Sep 18, 2004, in forum: Python
    Replies:
    2
    Views:
    747
    Pierre Fortin
    Sep 18, 2004
  4. er
    Replies:
    2
    Views:
    541
  5. Michael Tan
    Replies:
    32
    Views:
    1,074
    Ara.T.Howard
    Jul 21, 2005
Loading...

Share This Page