How to quote string with backtick in zsh? - zsh

I need to mount an SMB share with a line like
mount_smbfs //username:password#server.com/folder/ mountpoint
But my password contains backticks!
How would I quote this?
I've tried:
mount_smbfs //username:\`123\`123#server.com/folder/ mountpoint
And single quotes:
mount_smbfs '//username:`123`123#server.com/folder/' mountpoint
And a variable:
pw='`123`123'
mount_smbfs //username:$pw#server.com/folder/ mountpoint
All of which give me
mount_smbfs: URL parsing failed, please correct the URL and try again: Invalid argument

The same way you do any string that contains characters that need to be escaped:
mount_smbfs //username:my\`password#server.com/folder/
or
mount_smbfs '//username:my`password#server.com/folder/'
You can't use double quotes alone, because the backtick in a double-quoted string is interpreted as the start of a command substitution. You could write
mount_smbfs "//username:my\`password#server.com/folder/"
Based on the error message, the problem isn't protecting the backtick from the shell, but from the URL parsing library. Try
mount_smbfs '//username:%60123%60123#server.com/folder/' mountpoint
where %60 is the URL-quoted form for a backtick. Quoting the URL anyway is good practice: don't expose anything you don't want processed to the shell, even if you are sure there's nothing that the shell would process.

Related

How do you split a long database string into multiple lines in a UNIX shell script?

I have the string below stored in my database column:
"Your ack was rejected due to the following reason: \n -- Invalid code received. \n \n Please correct the error and resend."
\n is the new line character where I want to split the line.
Expected output:
"Your ack was rejected due to the following reason:
-- Invalid code received.
Please correct the error and resend it."
Please suggest unix/sed command
echo $STRING| sed 's/\\n/\n/g
This worked!
It is possible to enable interpretation of backslash escapes with the echo -e option. Given that the string may contain special characters, important to wrap it in quotes. No need to use Unix utilities like sed or awk
STRING=...
echo -e "$STRING"

Mix of parameter and command substitutions

I found this snippet of code (simplified)
while read item; do
echo -n "${(q)item} "
done
from here https://github.com/junegunn/fzf/blob/master/shell/key-bindings.zsh#L12
I don't understand the expression "${(q)item} ".
What is variable q, I didn't find any declaration of it, is it a command substitution? Why parentheses use inside curly braces? What is meaning of this construction?
Parentheses immediately after ${ specify parameter expansion flags. The q flag is used to quote special characters in the expansion.
Quote characters that are special to the shell in the resulting words with backslashes; unprintable or invalid characters are quoted using the $'\NNN' form, with separate quotes for each octet.

jenkins password encryption, escaping ${} characters

I am trying to encrypt the string ${PASSWD} using the following groovy script. using \ for escaping $ and \ for { or }
import hudson.util.Secret
def secret = Secret.fromString("\$\\{PASSWD\\}")
println(secret.getEncryptedValue())
def decrypt = Secret.fromString("/WaEf5KeDpbhnjW+hBmV3kmpmQbwoTFh2oI1yFSuUf0=")
println(decrypt.getPlainText())
I get the following output:
/WaEf5KeDpbhnjW+hBmV3kmpmQbwoTFh2oI1yFSuUf0=
/WaEf5KeDpbhnjW+hBmV3kmpmQbwoTFh2oI1yFSuUf0=
However, the desired output should have been
/WaEf5KeDpbhnjW+hBmV3kmpmQbwoTFh2oI1yFSuUf0=
${PASSWD}
It seems that I am not using escape characters properly. How can I pass ${PASSWD} as a string?
Just use single quotes
def secret = Secret.fromString('${PASSWD}')
Depending on where you want to escape things, this is very useful:
https://gist.github.com/Faheetah/e11bd0315c34ed32e681616e41279ef4
For using the secret storage, I needed to use the 6 times backslash to get 1 backslash, which I eventually needed in a sed command to escape forward slashes.

Handling "?" character passed to ZSH function

I'm having problem with setting up simple function in ZSH.
I want to make function which downloads only mp3 file from youtube.
I used youtube-dl and i want to make simple function to make that easy for me
ytmp3(){
youtube-dl -x --audio-format mp3 "$#"}
So when i try
ytmp3 https://www.youtube.com/watch?v=_DiEbmg3lU8
i get
zsh: no matches found: https://www.youtube.com/watch?v=_DiEbmg3lU8
but if i try
ytmp3 "https://www.youtube.com/watch?v=_DiEbmg3lU8"
it works.
I figured out that program runs (but wont download anything) if i remove all charachers after ? including it. So i guess that this is some sort of special character for zsh.
By default, the ZSH will try to "glob" patterns that you use on command lines (it will try to match the pattern to file names). If it can't make a match, you get the error you're getting ("no matches found").
You can disable this behaviour by disabling the nomatch option:
unsetopt nomatch
The manual page describes this option as follows (it describes what happens when the option is enabled):
If a pattern for filename generation has no matches, print an error, instead of leaving it unchanged in the argument list.
Try again with the option disabled:
$ unsetopt nomatch
$ ytmp3 https://www.youtube.com/watch?v=_DiEbmg3lU8
If you want to permanently disable the option, you can add the disable command to your ~/.zshrc file.
The question mark is part of ZSH's pattern matching, similarly to *. It means "Any character".
For instance, ls c?nfig will list both "config" and "cinfig", provided they exist.
So, yes, your problem is simply that zsh is trying to interpret the ? in the URL as a pattern to match to files, failing to find any, and crapping out. Escape the ? with a \ or put quotes around it, like you did, to fix it.

how does unix handle full path name with space and arguments?

How does unix handle full path name with space and arguments ?
In windows we quote the path and add the command-line arguments after, how is it in unix?
"c:\foo folder with space\foo.exe" -help
update:
I meant how do I recognize a path from the command line arguments.
You can either quote it like your Windows example above, or escape the spaces with backslashes:
"/foo folder with space/foo" --help
/foo\ folder\ with\ space/foo --help
You can quote if you like, or you can escape the spaces with a preceding \, but most UNIX paths (Mac OS X aside) don't have spaces in them.
/Applications/Image\ Capture.app/Contents/MacOS/Image\ Capture
"/Applications/Image Capture.app/Contents/MacOS/Image Capture"
/Applications/"Image Capture.app"/Contents/MacOS/"Image Capture"
All refer to the same executable under Mac OS X.
I'm not sure what you mean about recognizing a path - if any of the above paths are passed as a parameter to a program the shell will put the entire string in one variable - you don't have to parse multiple arguments to get the entire path.
Since spaces are used to separate command line arguments, they have to be escaped from the shell. This can be done with either a backslash () or quotes:
"/path/with/spaces in it/to/a/file"
somecommand -spaced\ option
somecommand "-spaced option"
somecommand '-spaced option'
This is assuming you're running from a shell. If you're writing code, you can usually pass the arguments directly, avoiding the problem:
Example in perl. Instead of doing:
print("code sample");system("somecommand -spaced option");
you can do
print("code sample");system("somecommand", "-spaced option");
Since when you pass the system() call a list, it doesn't break arguments on spaces like it does with a single argument call.
Also be careful with double-quotes -- on the Unix shell this expands variables. Some are obvious (like $foo and \t) but some are not (like !foo).
For safety, use single-quotes!
You can quote the entire path as in windows or you can escape the spaces like in:
/foo\ folder\ with\ space/foo.sh -help
Both ways will work!
I would also like to point out that in case you are using command line arguments as part of a shell script (.sh file), then within the script, you would need to enclose the argument in quotes. So if your command looks like
>scriptName.sh arg1 arg2
And arg1 is your path that has spaces, then within the shell script, you would need to refer to it as "$arg1" instead of $arg1
Here are the details
If the normal ways don't work, trying substituting spaces with %20.
This worked for me when dealing with SSH and other domain-style commands like auto_smb.

Resources