Tag Info

Hot answers tagged

36

Preamble First, I'd say it's not the right way to address the problem. It's a bit like saying "you should not murder people because otherwise you'll go to jail". Similarly, you don't quote your variable because otherwise you're introducing security vulnerabilities. You quote your variables because it is wrong not to (but if the fear of the jail can help, ...


24

In cd ~/z/ you are using Tilde expansion to expand ~ into your home directory. In BASE="~/z", you are not because you quoted the ~ character, so it is not expanded. That is why you get a message complaining about a nonexistent ~ directory. The solution is to not quote it, i.e. BASE=~/z in order to let the expansion occur.


20

The quotes protect the contents from shell wildcard expansion. Run that command (or even simpler just echo *test.txt in a directory with a footest.txt file and then one without any files that end in test.txt and you will see the difference. $ ls a b c d e $ echo *test.txt *test.txt $ touch footest.txt $ echo *test.txt footest.txt The same thing will ...


11

To be able to time a subshell, you need the time keyword, not command. The time keyword, part of the language, is only recognised as such when entered literally. Even entering "time" won't work let alone $TIME (and would be taken as a call to the time command instead). You could use aliases here which are expanded before another round of parsing is ...


10

@jw013 has given a valid explanation and solution. But there may be some cases when you do want to quote the paths, e.g. when they contain multiple spaces or special symbols. In this case you should use $HOME instead of ~, i.e. your BASE="~/z" will become BASE="$HOME/z" and work correctly, because parameter substitution is interpreted in double quotes, ...


6

Simple use: find . -size +1M -delete If you insist using xargs and rm with find, just add -print0 in your command: find . -size +1M -print0 | xargs -r0 rm -- Other way: find . -size +1M -execdir rm -- {} + From man find: -print0 True; print the full file name on the standard output, followed by a null character (instead of the newline ...


5

Option -0 of xargs means that output from pipe is interpreted as null terminated items. In such case you also need to create input for the pipe with find ... -print0.


4

The ' single quote character in your echo example gets it literal value (and loses its meaning) as it enclosed in double quotes ("). The enclosing characters are the double quotes. What you can do is print the single quotes separately: echo "'"'$a'"'" or escape the $: echo "'\$a'"


4

You're mixing character classes (a list of characters inside square brackets) with the smb.conf share names which are surrounded by square bracket literals. Also, the echo command is not well-formed: in the case where sed exits with a non-zero status, the shell will attempt to invoke the command Failed. A few suggestions: Remove the character class (outer ...


4

You have to escape ! to prevent csh/tcsh from performing history expansion. They still do history expansion though you wrote ! in single quote. Try: sed ':again;$\!N;$\!b again; s/{[^}]*}//g' file Or you can write a script an call with -f script.sed (Read sed FAQ).


3

While an alias is one way to do it, this can be done with eval as well - it's just that you don't so much want to eval the command execution as you want to eval the command declaration. I like aliases - I use 'em all the time, but I like functions better - especially their ability to handle parameters and that they needn't necessarily be expanded in command ...


3

Don't use backticks, use $(). Use single quotes around literal strings and double around variables, so echo "$test". Don't use echo, use printf. After all: $ test="$(printf '%s' '[asdf]')" $ printf "%s\n" "$test" [asdf]


3

Variables don't get evaluated in a single quoted string. You need to use double quotes. If you can't or don't want to use double quotes for the whole string you can use them for just that part of the string. ruby -rjson -e 'j = JSON.parse($stdin.read); puts j["ChgSub"]["'"$GHREPO"'"][0]["Major"].to_s' That is three separate quoted strings next to one ...


3

You misunderstand the documentation: having it's special meaning inside, would shield $ from the special interpretation "Having its special meaning" means that it is interpreted specially not literally. Single quotes prevent $ from being expanded. But single quotes within double quotes are literal characters i.e. they do not affect anything. If you ...


3

Try this (I tested on my machine and it appears to work---well, I didn't have any duplicates to remove, but...): ssh root@10.100.10.26 "awk '!seen[\$0]++' /root/.ssh/authorized_keys > /root/.ssh/authorized_keystemp" Your "-quote attempts didn't work since you didn't backslash the $ in $0, leading it to be expanded to something like bash. Your ...


2

The simplest answer is to escape the [ so that it isn't treated as a special pattern character. (The closing ] is treated literally if it isn't preceded by an unquoted [.) test=$(echo \[asdf])


2

Remove the \ from before the space. An escaped space is used to stop the shell splitting at spaces. As you are using a file to list your excluded directories and files then the words Mendeley Desktop will never pass through the shell and therefore will not need escaping. If you were listing them on the command line with --exclude then you'd need to escape ...


2

You should always avoid mixing languages as much as possible. In this case you are trying to mix shell script into ruby script. Mixing languages convolutes your code and makes it fragile. The solution in this case is to use ruby's native environment variable support. $ GHREPO=ecx ruby -rjson -e 'j = JSON.parse($stdin.read); puts ...


2

Use an array since that can expand to a variable number of arguments: #!/bin/bash # This is file caller.bash switch=() if [[ ${1-x} == x ]] then switch=("--abc=long argument") fi some_command.sh "--exclude=*~" "${switch[@]}" arg Or you could use the ${var+...} syntax: #!/bin/sh # This is file caller.sh unset switch if [ "${1-x}" = x ] then ...


2

String interpolation causes this. There are a number of ways to selectively prevent this from happening. The bash hackers wiki has some good examples, though the specifics may vary if you're not actually using bash. In short, you can prevent interpolation with single quotes, or you can escape the characters. [me:~/work]$ export foo=bar [me:~/work]$ echo ...


2

It's nothing to do with SSH. The -x argument to bash is that of bash's set command, which displays the command's arguments in expanded form. This is why the double quoted strings are displayed as single quoted strings. $ cat test.sh echo "here are 'some single quotes' inside double quotes" $ bash -x test.sh + echo 'here are '\''some single quotes'\'' ...


1

It seems a common workaround to execute sh, which will resolve the special symbols and variables correctly: Exec=sh -c "java -jar \~/.minecraft/Minecraft.jar"


1

To complement the other answers, zsh, fish and (t)csh are more helpful here in that they can help you show your mistake before it becomes a problem: If there's no *test.txt file in the current directory: zsh$ find . -name *test.txt zsh: no matches found: *test.txt fish> find . -name *test.txt fish: No matches for wildcard '*test.txt'. find . -name ...


1

tl;dr version You are passing a string literal to the command/program, just like double-quotes but differ that single-quotes prevent variable and wildcard expansion while double-quotes expand them in to the string literal. Example: $ export MY_VAR=my_string $ echo "$MY_VAR" my_string $ echo '$MY_VAR' $MY_VAR The same applies to wildcards Hope it helps. ...



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