How to pass command line parameters with quotes stored in single variable?
Answering my own question. BIG thanks goes to pzanoni.
xargs seems to parse correctly anything you are throwing to it :-)
"$@", "$", $@ and $ works good with it. So my code now looks like:
#!/bin/sh
pass() {
echo $* | xargs ./sh_param
}
pass '"single param" separate params'
And result is what I wanted:
Param: single param
Param: separate
Param: params
Expansion of variables inside single quotes in a command in Bash
Inside single quotes everything is preserved literally, without exception.
That means you have to close the quotes, insert something, and then re-enter again.
'before'"$variable"'after'
'before'"'"'after'
'before'\''after'
Word concatenation is simply done by juxtaposition. As you can verify, each of the above lines is a single word to the shell. Quotes (single or double quotes, depending on the situation) don't isolate words. They are only used to disable interpretation of various special characters, like whitespace, $
, ;
... For a good tutorial on quoting see Mark Reed's answer. Also relevant: Which characters need to be escaped in bash?
Do not concatenate strings interpreted by a shell
You should absolutely avoid building shell commands by concatenating variables. This is a bad idea similar to concatenation of SQL fragments (SQL injection!).
Usually it is possible to have placeholders in the command, and to supply the command together with variables so that the callee can receive them from the invocation arguments list.
For example, the following is very unsafe. DON'T DO THIS
script="echo \"Argument 1 is: $myvar\""
/bin/sh -c "$script"
If the contents of $myvar
is untrusted, here is an exploit:
myvar='foo"; echo "you were hacked'
Instead of the above invocation, use positional arguments. The following invocation is better -- it's not exploitable:
script='echo "arg 1 is: $1"'
/bin/sh -c "$script" -- "$myvar"
Note the use of single ticks in the assignment to script
, which means that it's taken literally, without variable expansion or any other form of interpretation.
How do I pass on script arguments that contain quotes/spaces?
Use "$@"
with quotes:
prog="$1"
"$@"
ecode="$?"
echo "$prog exited with $ecode"
This will pass each argument exactly as it was received. If you don't include the quotes, each element will be split according to $IFS
:
"$@"
is like"$1" "$2" "$3" ...
, passing each element as a separate argument."$*"
is like"$1 $2 $3 ..."
, passing all elements concatenated as a single argument$*
and$@
is like$1 $2 $3 ...
, breaking up each element on whitespace, expanding all globs, and passing each resulting word as a separate element ($IFS
).
The same is true for arrays, such as "${array[@]}"
and "${array[*]}"
How would I make a variable of type args take a quote or string as an argument among others?
You can treat quoted text as one string without using the Split function, instead making use of Regex.
Take the following snippet as an example:
// In your case just read from the textBox for input
string input = "cars \"testing string\"";
// This code will split the input string along spaces,
// while keeping quoted strings together
string[] tmp = Regex.Split(input,
"(?<=^[^\"]*(?:\"[^\"]*\"[^\"]*)*) (?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
// Now must remove the quotes from the Regex'd string
string[] args = tmp.Select(str => str.Replace("\"", "")).ToArray();
// Now when printing the arguments, they are correctly split
for (int i = 0; i < args.Length; i++)
{
Console.WriteLine("args[" + i + "]:'" + args[i] + "'");
}
I found the particular regex string you needed at this link, here on stack overflow.
Keep quotes in $args using PowerShell
The only way I can think of without being able to modify the input parameters would still require modifying the command called somewhat.
In order to preserve the quotes, perhaps try capturing the full command-line that the PowerShell script was called with.
So I put this in the test1.ps1 script:
Write-Host (Get-WmiObject -Query "select CommandLine from Win32_Process where CommandLine like '%test1%'").CommandLine
Then this is what is returned if the script is called in this manner:
PS C:\temp> powershell .\test1.ps1 a=application o="this object" msg_text="this is a text"
"C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" .\test1.ps1 a=application "o=this object" "msg_text=this is a text"
This is only possible if a new instance of PowerShell is called, however, otherwise the parameters won't be available by this method:
PS C:\temp> .\test1.ps1 a=application o="this object" msg_text="this is a text" > zzz3.txt
PS C:\temp>
Of course if this approach is taken, you'll then need to parse the input arguments manually, which you might be able to do with help of the $args
object. It's a long-shot, but does preserve the quotes.
How to quotes in bash function parameters?
The reason this happens is because bash interprets the arguments, as you thought. The quotes simply aren't there any more when it calls the function, so this isn't possible. It worked in DOS because programs could interpret the command line themselves, not that it helps you!
Related Topics
Limit Useable Host Resources in Docker Compose Without Swarm
Bash Alias Create File with Current Timestamp in Filename
How to Grep While Avoiding 'Too Many Arguments'
What Does Version Info in Ldd -V Mean
Dbus_Bus_Request_Name (): Connections Are Not Allowed to Own the Service
Compare Md5 Sums in Bash Script
Can't Clone on Windows But Can Clone on Linux from Gitlab Server
Escaping Quotes in Bash (Embedded Awk)
Passing Environment Variables Not Working with Docker
Linux /Bin/Sh Check If String Contains X
Chef Chef-Validator.Pem Security
How Can Linux Ptrace Be Unsafe or Contain a Race Condition
How to Replace a Multi Line String in a Bunch Files