Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have one-line that I want to call using alias.

while printf '%s ' "$(df -P / | awk 'NR==2 { print $(NF-1) }')"; do sleep 30; done

I tried to escape ' like \' but it didn't work.

What is the correct syntax to use above one-liner in alias?

share|improve this question

5 Answers 5

up vote 4 down vote accepted
alias my_du=$'while printf \'%s \' "$(df -P / | awk \'NR==2 { print $(NF-1) }\')"; do sleep 3; done'

You can check the result with

alias my_du

If $() is quoted by " instead of ' or \ then it is substituted and the result rather than the intended program call becomes part of the alias definition.

share|improve this answer
    
Works smoothly, thank you. Could you explain to me $ at the beginning? –  Radek Apr 23 '13 at 23:27
1  
@Radek Have a look at the man page, block "QUOTING" (starting on line 341 here). $'' is a special kind of quoting which does not just quote but also enables escape sequences (like printf, e.g. $'\n' for newline). That is actually the more important part than the better quoting of '. Everyone who does shell scripting (with bash) should be familiar with this. –  Hauke Laging Apr 24 '13 at 2:31

You can't escape single quotes whilst still in single quotes because \ is taken literally in a single quote context. Either close the single quotes before escaping, or, better, use double quotes.

alias my_du="while printf '%s ' \"\$(df -P / | awk 'NR==2 { print \$(NF-1) }')\"; do sleep 30; done"
share|improve this answer
1  
That is not completely correct: echo $'\'' –  Hauke Laging Apr 23 '13 at 7:47
    
@HaukeLaging $' and ' are totally different, and not related -- $' is definitely not suitable in this situation. You might as well compare " and $". –  Chris Down Apr 23 '13 at 7:50
1  
You should have a look at alias my_du to see what your proposal does. Why that does not work. Or you may run strace -p $PID -f -e trace=process against the shell and run the alias and wonder why neither df nor awk get executed. Funny that you call $' "definitely not suitable in this situation" because that one does work. –  Hauke Laging Apr 23 '13 at 8:16
    
@ChrisDown, Hauke Laging has a good point: you forgot to escape the $ signs, so the command substitution takes place when the alias is defined, not when is executed. –  manatwork Apr 23 '13 at 8:31
    
Someone tells you about strace test results and you don't even check the output of alias my_du as advised? Wow, what a self-confidence. Your definition of "works" is funny. Indeed, your code creates that output. I didn't doubt that. It just does not change the output if the file system situation changes. –  Hauke Laging Apr 23 '13 at 8:33

While this can be coaxed into an alias, functions are generally preferred. From man bash:

For almost every purpose, aliases are superseded by shell functions.

Your alias in function form:

my_du() {
    while printf '%s ' "$(df -P / | awk 'NR==2 { print $(NF-1) }')"
    do
        sleep 30
    done
}

That's more readable, and as such more maintainable.

share|improve this answer

If you want commands that take arguments or interact in any way with their environment, use functions. At least in bash, aliases are expanded when defined, they might act as if they took arguments or used variables. Sometimes. Murphy's law ensures that that won't work when really needed.

share|improve this answer

You can't use a backslash to escape a single quote inside a single-quoted string because the backslash itself is interpreted literally.

You can effectively escape a single quote inside a single-quoted string by writing the 4-character sequence '\''. Formally this terminates the single-quoted literal, appends a literal single quote, and starts a new single-quoted literal. The end result is that you have a single quote character in the middle of a single-quoted literal.

alias foo='while printf '\''%s '\'' "$(df -P / | awk '\''NR==2 { print $(NF-1) }'\'')"; do sleep 30; done'

I wouldn't recommend such a complex alias. Aliases are primarily meant to give a short name to a command, possibly with switches. This goes well beyond their comfort range. Use a function instead.

foo () {
  while printf '%s ' "$(df -P / | awk 'NR==2 { print $(NF-1) }')"; do sleep 30; done
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.