Unable to delete file
I am unable to delete file:
sudo rm /usr/local/bin/Katy Perry - Dark Horse (Official) ft. Juicy J-0KSOMA3QBU0.mp4.part
It is showing an error:
bash: syntax error near unexpected token `('
How to fix it?
Solution 1:
Tab Completion
If you only have one file in /usr/local/bin
whose name starts with Katy
, you can simply type
sudo rm /usr/local/bin/Katy
without pressing Enter yet. Then press Tab to complete the command to:
sudo rm Katy\ Perry\ -\ Dark\ Horse\ \(Official\)\ ft.\ Juicy\ J-0KSOMA3QBU0.mp4.part
(And then press Enter to run it.)
This quotes each character individually (as in AliNa's answer), and does so automatically so you don't miss anything.
In practice, a large amount of quoting we do on the command line is actually achieved automatically with tab completion.
Note also that tab completion is not limited to situations where something would have to be quoted. For example, a UUID like 8d44cd38-2158-42f4-9af1-94cd3ccbb9a8
doesn't need to be quoted but if it's the only possibility starting with 8
(or with some longer initial proper subsequence), tab completion could be very handy for composing a command containing it.
You can also manually quote, in which case you'll want to know about other ways of quoting than \
, for cases like this one where many characters have to be quoted and mistakes are easy to make.
Manual Quoting with '
If you want an expression to appear literally, and the expression doesn't contain a single quote characater ('
), a good habit to get into is to quote it using single quotes.
sudo rm '/usr/local/bin/Katy Perry - Dark Horse (Official) ft. Juicy J-0KSOMA3QBU0.mp4.part'
You can quote all of an argument, or just part of it. For example, this works too:
sudo rm /usr/local/bin/'Katy Perry - Dark Horse (Official) ft. Juicy J-0KSOMA3QBU0.mp4.part'
Or even:
sudo rm /usr/local/bin/Katy' Perry - Dark Horse (Official) ft. Juicy 'J-0KSOMA3QBU0.mp4.part'
(I've italicized the portions of the above commands that are quoted, so the effects of '
can be seen.)
When quoting with '
, only '
is treated specially. It is always matched as a closing quote mark.
In contrast, quoting with double quotes, as is widely recommended (even when unnecessary), will usually work but operates in accordance with quite complex rules.
Manual Quoting with "
There are three common cases where quoting with "
is used in preference over '
.
For some reason, many people stylistically prefer
"
. This is not necessarily wrong or undesirable, but I recommend against preferring"
unless you're familiar and comfortable with the rules of which shell expansions it does and does not prevent.-
When your expression contains a single quote character (
'
), this cannot be enclosed in single quotes, but it can be enclosed in double quotes. And like'
,"
quoting removes special meaning from spaces, tabs, newlines (line breaks),(
and)
,{
and}
,<
and>
,;
,&
,|
,?
,*
,~
and#
. (And possibly other characters, depending on if I'm forgetting anything and on what shell options are enabled.) For example:du -h "Don't Ask Me Why (Eurythmics, 1989).flac"
Thus double quotes work fine for the particular file you were deleting--whose name contained the special characters
(
,)
, and space--and the suggestion to use them in this case was both helpful and perfectly okay. -
However, unlike
'
, quoting with"
does not remove the special meaning from$
,`
,\
, and (unless history expansion is disabled)!
. (Nor"
, which as you'd expect is interpreted as the closing double quote. Usually.)"
quoting is thus useful when you don't want to prevent the shell from performing expansions based on the meaning of those characters. For example, runningf='fee fi fo'
followed bycat "$f fum.txt"
prints the contents offee fi fo fum.txt
.But when such behavior is unanticipated, it can cause problems:
$ du -sh ... $ rm "Stupid Scheme to Make $$$$$$ Quick!!!!.pdf" rm "Stupid Scheme to Make $$$$$$ Quickdu -shdu -sh.pdf" rm: cannot remove ‘Stupid Scheme to Make 453745374537 Quickdu -shdu -sh.pdf’: No such file or directory
Characters that retain their special meaning within
"
quotes can themselves be quoted by being preceded by a\
:$ echo "\"Windows uses '\\' as the path separator,\" screeched Multiplatform Owl wisely." "Windows uses '\' as the path separator," screeched Multiplatform Owl wisely.
When an unquoted
\
precedes a character that doesn't need further quoting, it remains unchanged. (Thus\\
in the above command could simply have been a single\
.)Inside double quotes,
\
before!
removes it special meaning (i.e., prevents history expansion). But unlike when\
quotes other special characters, a\
before!
is not removed. Thus,\!
is interpreted as a literal\!
, whereas\$
is interpreted as a literal$
and\
before a space is interpreted as a literal space.
Manual Quoting with \
\
quotes a single character, the character immediately following it. (Except of course when it is itself quoted.)
For most characters x
, \x
is equivalent to x
. \
is specifically useful when the character following it has special meaning--it removes special meaning from that character:
$ rm -v Stupid\ Scheme\ to\ Make\ \$\$\$\$\$\$\ Quick\!\!\!\!.pdf
removed ‘Stupid Scheme to Make $$$$$$ Quick!!!!.pdf’
When \
is enclosed in double quotes ("
), it works differently, as described above. It then has special meaning only when the following character is special, and otherwise is interpreted literally.
Manually writing commands with \
is especially useful and appropriate when you don't have to use very many of them, and can be somewhat inefficient otherwise.
For example:
ek@Ilex:~$ pastebinit <<< Hello,\ world!
http://paste.ubuntu.com/8390449/
(A single !
character at the end of an argument doesn't need to be quoted.)
Combining Different Forms of Quoting
Suppose you wanted to couldn't wouldn't shouldn't can't won't don't!!
to appear literally. An easy way to achieve this would be to quote it as:
"couldn't wouldn't shouldn't can't won't don't"'!!'
Or (since \
before !
only fails to be removed when double-quoted):
"couldn't wouldn't shouldn't can't won't don't"\!\!
This can be combined with, and may be considered a variation on, quoting only part of an argument, as discussed above.
Sources / Further Reading
- Bash Reference Manual (see this page for other formats)
-
man bash
(a.k.a. bash(1), the bash manpage)