Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I obtain unmodified command line arguments to "wrap" another command line tool?

I want to write a script foo which simply calls bar with the exact same arguments it was called with, using Bash or Perl.

Now, a simply way to do this in perl would be

#!/bin/perl

my $args=join(' ', @ARGV);
`bar $args`;

However, the values in ARGV have already been processed by the shell, thus if I call

 foo "I wonder, \"does this work\""

bar would get called like this

 bar I wonder "does this work"

How can I obtain the original command line so that I can simply pass it on verbatim?

like image 385
Paul Dixon Avatar asked Nov 19 '09 18:11

Paul Dixon


People also ask

How do I get command line arguments?

Command-line arguments are given after the name of the program in command-line shell of Operating Systems. To pass command line arguments, we typically define main() with two arguments : first argument is the number of command line arguments and second is list of command-line arguments.

What is used for all command line arguments?

Command line arguments are passed to the main function as argc and argv. Command line arguments are used to control the program from the outside. argv[argc] is a Null pointer. The name of the program is stored in argv[0], the first command-line parameter in argv[1], and the last argument in argv[n].

Where does the command line argument as get stored?

All the command line arguments are stored in a character pointer array called argv[ ]. Total count of command line arguments including file path argument is stored in a integer parameter called argc.

How are command line arguments separated?

Each argument on the command line is separated by one or more spaces, and the operating system places each argument directly into its own null-terminated string. The second parameter passed to main() is an array of pointers to the character strings containing each argument (char *argv[]).

Can you pass command line arguments?

It is possible to pass some values from the command line to your C programs when they are executed. These values are called command line arguments and many times they are important for your program especially when you want to control your program from outside instead of hard coding those values inside the code.


3 Answers

You can't get the arguments to the perl executable before they were processed by the shell. You can, however, ensure that the shell doesn't process them again:

system('bar', @ARGV);

vs.

system("bar @ARGV");

See perldoc -f system:

If there is only one scalar argument, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is "/bin/sh -c" on Unix platforms, but varies on other platforms). If there are no shell metacharacters in the argument, it is split into words and passed directly to "execvp", which is more efficient.

If you need to read the output of the program, use a process handle and pass the arguments in the same way (without interpolation):

open my $barhandle, '-|', 'bar', @ARGV or die "Can't call bar: $!";
while (my $line = <$barhandle>)
{
    # do something with $line...
}
close $barhandle;

There are lots of ways you can call out to a program in Perl; see What's the difference between Perl's backticks, system, and exec? for a good overview of the major options.

like image 162
Ether Avatar answered Sep 17 '22 19:09

Ether


It's extremely simple. Check out the system(LIST) variant of system calls.

system('bar', @ARGV);

perldoc -f system

like image 41
tsee Avatar answered Sep 19 '22 19:09

tsee


In bash:

exec bar "$@"

This preserves the spacing in the arguments. I/O redirection, though, is not an argument within the meaning of the term (but the I/O redirection done for the original invocation would persist to the invoked 'bar' command unless you change it).

like image 36
Jonathan Leffler Avatar answered Sep 21 '22 19:09

Jonathan Leffler