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?
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.
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].
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.
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[]).
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.
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.
It's extremely simple. Check out the system(LIST) variant of system calls.
system('bar', @ARGV);
perldoc -f system
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With