Tag Info

Hot answers tagged

72

Use "--" to make rm stop parsing command line options, like this: rm -- --help


41

First, you need to protect the pattern from expansion by the shell. The easiest way to do that is to put single quotes around it. Single quotes prevent expansion of anything between them (including backslashes); the only thing you can't do then is have single quotes in the pattern. grep 'foo*' *.txt If you do need a single quote, you can write it as '\'' ...


41

You need to quote your argument error* because the shell expands it. So what you're actually running now is find -name error_log, because that's what the shell can expand it to (there's a file named error_log in your current directory). find . -name 'error*' Is the correct invocation for your use case.


34

There are two different things going on here, both documented in the bash manual $' Dollar-sign single quote is a special form of quoting: ANSI C Quoting Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. $" Dollar-sign double-quote is for ...


29

In the same way that you can't run ls "*.txt" in a normal shell, you can't run it in a subshell either. When you put *.txt in quotes, you made ls search for a literal file called *.txt when instead you should be doing this: $ echo $(ls *.txt) # => file.txt otherfile.txt A better way to do this is to not use ls at all. $ echo *.txt # => file.txt ...


28

The single bracket [ is actually an alias for the test command, it's not syntax. One of the downsides (of many) of the single bracket is that if one or more of the operands it is trying to evaluate return an empty string, it will complain that it was expecting two operands (binary). This is why you see people do [ x$foo = x$blah ], the x guarantees that ...


27

This is a backtick. Backtick is not a quotation sign, it has a very special meaning. Everything you type between backticks is evaluated (executed) by the shell before the main command (like chown in your examples), and the output of that execution is used by that command, just as if you'd type that output at that place in the command line. So, what sudo ...


26

VAR=$VAR1 is a simplified version of VAR=${VAR1}. There are things the second can do that the first cant, for instance reference an array index (not portable) or remove a substring (POSIX-portable). See the More on variables section of the Bash Guide for Beginners and Parameter Expansion in the POSIX spec. Using quotes around a variable as in rm -- "$VAR1" ...


26

Short answer: Try this: 0 * * * * echo hello >> ~/cron-logs/hourly/test`date "+\%d"`.log Note the backslash escaping the % sign. Long answer: The error message suggests that the shell which executes your command doesn't see the second back tick character: /bin/sh: -c: line 0: unexpected EOF while looking for matching ``' This is also ...


26

Always use double quotes around variable substitutions and command substitutions: "$foo", "$(foo)" If you use $foo unquoted, your script will choke on input or parameters (or command output, with $(foo)) containing whitespace or \[*?. There, you can stop reading. Well, ok, here are a few more: read — To read input line by line with the read builtin, use ...


25

${VAR} and $VAR are exactly equivalent. For a plain variable expansion, the only reason to use ${VAR} is when parsing would otherwise grab too many characters into the variable name, as in ${VAR1}_$VAR2 (which without braces would be equivalent to ${VAR1_}$VAR2). Most adorned expansions (${VAR:=default}, ${VAR#prefix}, …) require braces. In a variable ...


25

Dealing with multiple levels of quoting (really, multiple levels of parsing/interpretation) can get complicated. It helps to keep a few things in mind: Each “level of quoting” can potentially involve a different language. Quoting rules vary by language. When dealing with more than one or two nested levels, it is usually easiest to work “from the bottom, ...


25

In bash you can use the syntax str=$'Hello World\n===========\n' Single quotes preceded by a $ is a new syntax that allows to insert escape sequences in strings. Also printf builtin allows to save the resulting output to a variable printf -v str 'Hello World\n===========\n' Both solutions do not require a subshell. If in the following you need to ...


25

There are two levels of interpretation here: the shell, and sed. In the shell, everything between single quotes is interpreted literally, except for single quotes themselves. You can effectively have a single quotes between single quotes by writing '\'' (close single quote, one literal single quote, open single quote). Sed uses basic regular expressions. ...


25

Remove the quotes around *.txt and it should work. With quotes shell will look for the literal filename *.txt. To explore/experiment, try creating a file with name *.txt as touch '*.txt' and repeat the command.


25

In order from worst to best: DIRNAME="$(dirname $FILE)" will not do what you want if $FILE contains whitespace or globbing characters \[?*. DIRNAME=`dirname "$FILE"` is technically correct, but backticks are not recommended for command expansion because of the extra quoting issues when nesting them. DIRNAME=$(dirname "$FILE") is correct, but only because ...


24

This is used for alias protection: $ ls .bashrc a b $ alias ls alias ls='ls $LS_OPTIONS' $ \ls a b


20

The exclamation mark is part of history expansion in bash. To use it you need it enclosed in single quotes (eg: 'http://example.org/!132') or to directly escape it with a backslash (\) before the character (eg: "http://example.org/\!132").


18

You always need quotes around variables in all list contexts, that is everywhere the variable may be expanded to multiple values unless you do want the 3 side effects of leaving a variable unquoted. list contexts include arguments to simple commands like [ or echo, the for i in <here>, assignments to arrays... There are other contexts where variables ...


18

First, separate zsh from the rest. It's not a matter of old vs modern shells: zsh behaves differently. The zsh designers decided to make it incompatible with traditional shells (Bourne, ksh, bash), but easier to use. Second, it is far easier to use double quotes all the time than to remember when they are needed. They are needed most of the time, so you'll ...


18

No need for any fancy stuff. Simply escape the ? so that it's not considered part of the glob: rm -f ./\?* This works for ! too: rm -f ./\!* Or in one fell swoop: rm -f ./{\?,\!}* Update Just noticed that you were suggesting to grep the output of ls. I wanted to bring your attention to the fact that you shouldn't parse the output of ls


17

When they are not quoted, $* and $@ are the same. You shouldn't use either of these, because they can break unexpectedly as soon as you have arguments containing spaces or wildcards. "$*" expands to a single word "$1c$2c...". Usually c is a space, but it's actually the first character of IFS, so it can be anything you choose. The only good use I've ...


17

You can use the arithmetic expansion instead. echo $(( 3 * ( 2 + 1 ) )) 9 In my personal opinion, this looks a bit nicer than using expr. From man bash Arithmetic Expansion Arithmetic expansion allows the evaluation of an arithmetic expression and the substitution of the result. The format for arithmetic expansion is: $((expression)) ...


16

You can put literal newlines within single quotes (in any Bourne/POSIX-style shell). str='Hello World =========== ' For a multiline string, here documents are often convenient. The string is fed as input to a command. mycommand <<'EOF' Hello World =========== EOF If you want to store the string in a variable, use the cat command in a command ...


16

The * (star, or asterisk) is a special character which is (usually) interpreted by the shell before it is given the command. It is (usually) expanded to all filenames except those with leading dots. See the bash manual about pattern matching for more information. If placed in quotes the star will not be interpreted by the shell and is given to the command ...


16

Another way to use let bash builtin: $ let a="3 * (2 + 1)" $ echo $a 9 Note As @Stéphane Chazelas pointed out, in bash you should use ((...)) to do arithmetic over expr or let for legibility. For portability, use $((...)) like @Bernhard answer.


15

As well as the answer given by Daniel, you can also simply turn off history expansion altogether if you don't use it with set +H.


13

The answers of Vegar Nilsen and edfuh are very good and the proper solutions to a problem like this. I do want to add a general response to this question that allows you to delete any file with a difficult file name. First its inode number is obtained using ls -i or some form of stat and then the file is removed by searching for files in the current ...


13

The [ command is an ordinary command. Although most shells provide it as a built-in for efficiency, it obeys the shell's normal syntactic rules. [ is exactly equivalent to test, except that [ requires a ] as its last argument and test doesn't. The double brackets [[ … ]] are special syntax. They were introduced in ksh (several years after [) because [ can ...



Only top voted, non community-wiki answers of a minimum length are eligible