bash + Linux + how to ignore the character !
Use set +H
before your command to disable ! style history substitution
:
set +H
ssh 183.34.4.9 "echo -e '#!/bin/bash\nsleep 1\reboot>'/tmp/file"
# enable hostory expnsion again
set -H
How do I escape an exclamation mark in bash?
Exclamation mark is preserved literally when you include it in a single-quoted string.
Example:
git commit -m 'Frustrating <insert object of frustration here>!'
How to pass argument with exclamation mark on Linux?
You should be able to simply wrap things in single quotes in the shell.
$ emailsender.py -u username -p 'pass!!'
Curl - Exclamation mark in User Auth/Password
curl -u UserName\\WithSlash:PasswordWithExclamation\! http://....
works fine.
it sends
GET / HTTP/1.1
Authorization: Basic VXNlck5hbWVcV2l0aFNsYXNoOlBhc3N3b3JkV2l0aEV4Y2xhbWF0aW9uIQ==
User-Agent: curl/7.21.0
Host: teststuff1.com:80
Accept: */*
which is "UserName\WithSlash:PasswordWithExclamation!" in the auth string.
Escaping characters in bash alias
Best Advice: Don't.
Use a function instead:
th() { tmux new -s "${PWD##*/}" "$@"; }
${PWD##*/}
is a parameter expansion which strips everything up to and including the last /
from the contents of $PWD
.
Alternate Approach: Literal Quotes
The issue in your original code is that it contains syntactic quotes -- ones parsed by the shell to determine where single-quoted parsing rules begin and end -- in places where what you actually want is literal quotes, ones which are treated as data (and thus become part of the alias).
One way to make these quotes literal would be to use the $''
quoting form instead, which lets you use literal backslashes to escape inner quotes, making them literal rather than syntactic:
alias th=$'tmux new -s $(pwd | tr \'\\\/\' \'\\n\' | tail -n 1)'
Note that when using $''
, literal backslashes need to be escaped as well (thus, written as \\
rather than \
).
Explanation: Why
The quoting of strings in POSIX shell languages is determined on a character-by-character basis. Thus, in the case of:
'$foo'"$((1+1))"baz
...$foo
is single-quoted and thus treated as a literal string, $((1+1))
is double-quoted and thus eligible for being treated as arithmetic expansion, and baz
is unquoted -- even though all three of these are concatenated to form a single word ($foo2baz
).
These quotes are all syntactic -- they're instructions to the shell -- not literal (which would mean they'd be part of the data to which that string evaluates).
How This Applies To Your Previous Command
In
alias th='tmux new -s $(pwd | tr '\/' '\n' | tail -n 1)'
...the single quotes in the arguments to tr
end the single quotes started at the beginning of the alias. Thus, \/
and \n
are evaluated in an unquoted context (in which \/
becomes just /
, and \n
becomes just n
) -- and since, as described above, multiple differently-quoted substrings can just be concatenated into a single larger string, you get your prior command, not an alias.
Single quotes around variable value
Like every other command the assignment of a value to a variable will be parsed by the shell, too. To prevent the shell from parsing the special characters must be "quoted". Single characters can be quoted with the backslash (\), multiple characters can be quoted with single quotes (') or double quotes ("). Within single quotes every character will be taken literally. Double-quoted characters will mostly taken literally, with the main exeption (among some others): variables will be replaced with their contents.
To assign the Value "JSBDbshe66!#12$@a" in the command line it must be single-quoted because of the bang (!) sign (see bash bang for further information):
:~$ DEV_ARM_CLIENT_SECRET='JSBDbshe66!#12$@a'
The command
:~$ echo $DEV_ARM_CLIENT_SECRET
gives you the desired output:
JSBDbshe66!#12$@a
To copy this value to another variable just enter in the command line:
ARM_CLIENT_SECRET=$DEV_ARM_CLIENT_SECRET
Alternatively you can enter:
ARM_CLIENT_SECRET="$DEV_ARM_CLIENT_SECRET"
to receive the same result. The variable-name between the double quotes will be replaced with the value and finally the shell removes the Quotes. If you put the variable name between single quotes
ARM_CLIENT_SECRET='$DEV_ARM_CLIENT_SECRET'
every character between the quotes will be taken literally:
:~$ echo $ARM_CLIENT_SECRET
$DEV_ARM_CLIENT_SECRET
If you quote the single quotes via Backslash
:~$ ARM_CLIENT_SECRET=\'$DEV_ARM_CLIENT_SECRET\'
the value of "$ARM_CLIENT_SECRET" will be the same as $DEV_ARM_CLIENT_SECRET with an additional leading and a trailing single quote:
:~$ echo $ARM_CLIENT_SECRET
'JSBDbshe66!#12$@a'
Related Topics
Phusion Passenger Nginx Module Installer V3.0.17 Issue on Debian 6.0.5 Amd64 Due to Broken Package
How to Feed Awk Input from Both Pipe and File
How to Offload the 1Hz Tick in Dyntick Mode
Shell Script Issue with Filenames Containing Spaces
Bash - Concatenating Variable on to Path
How to Print Current Time in Kernel
How to Modify Eip's Tracee Forked Procee
How to Stop Apache from Listing the Contents of My User Directories
How to Detect a Blank Column in a Page Using Imagemagick to Distinguish Two Column Papers
Bash/Linux Sort by 3Rd Column Using Custom Field Seperator
How to Get Around the Linux "Too Many Arguments" Limit
What Is a Good Linux Exit Error Code Strategy
Multiple -A with Greater Than/Less Than Break Bash Script
Batch Remove Substring from Filename with Special Characters in Bash
Webpack Build Fails with Gitlab-Ci
How to Set a Non-Standard Baudrate on a Serial Port Device on Linux