0

I am new to the Linux environment. After a quick search I could not find a helpful question about the $ operator used in bash scripting. I do not know if this question relates more to the Ubuntu (or other) flavor of Linux, or my oh-so-small programming experience with it.

Basically I thought the ~ operand in Linux was perfectly equivalent to the string '/home/username'. If I try to execute a program after a certain delay by using a bash script and an external C-based program, I am so stuck: I cannot make use of the ~ operand and keep the program indifferent to the user (though the rest of the file path must be respected).

Please provide comments to the following (finding the getIdle sources is left to the reader):

#!/bin/bash
# call.sh

idle=false
idleAfter=30000     # consider idle after 30000 ms

# EXPLAIN THIS - Begin
# Strings that work
# str_getIdle_exe='/home/seb/Documents/Seb/Prjcts/Idle/getidle/src/getIdle'
# str_getIdle_exe="/home/seb/Documents/Seb/Prjcts/Idle/getidle/src/getIdle"

# Strings that don'work
str_getIdle_exe='~/Documents/Seb/Prjcts/Idle/getidle/src/getIdle'
# str_getIdle_exe="~/Documents/Seb/Prjcts/Idle/getidle/src/getIdle"
# EXPLAIN THIS - End


while true; do
  idleTimeMillis= $str_getIdle_exe
  echo $idleTimeMillis  # just for debug purposes.
  if [[ $idleTimeMillis -gt $idleAfter && $idle = false  ]] ; then
    echo "start idle"   # or whatever command(s) you want to run...
    idle=true
    /usr/bin/xflock4
  else  # just for debug purposes.
    echo "not there yet..."
  fi

  if [[ $idleTimeMillis -lt $idleAfter && $idle = true ]] ; then
    echo "end idle"     # same here.
    idle=false
  fi
  sleep 1      # polling interval

done

What I am trying to explain is: why the two different strings above execute nicely in a shell, but not when called from a script?

I'm using Linux Mint 17.1 "Rebecca" Xfce (64-bit).

Many, many thanks.

2 Answers 2

1

The tilde is not expanded when in quotes -- ref: https://www.gnu.org/software/bash/manual/bashref.html#Tilde-Expansion

So you want to remove the quotes:

str_getIdle_exe=~/Documents/Seb/Prjcts/Idle/getidle/src/getIdle

If the path under your homedir contains a space, just leave the tilde unquoted:

some_path=~/"dir with spaces/file with spaces"
5
  • Perhaps worth noting that ~ isn't even expanded within double quotes - unlike $HOME. So $HOME may be preferable when quoting to prevent word-splitting e.g. "$HOME/some path/with spaces/" Jan 25, 2015 at 23:18
  • Thank you both. Given a choice I would pick str_getIdle_exe="$HOME/Documents/Seb/Prjcts/Idle/getidle/src/getIdle" but it turns out for my purposes I discovered that I cannot call ANY VARIABLE with $. Got to use idleTimeMillis=$(./getIdle) # doesn't need str_getIdle_exe variable. $ operation on variables may return a number string, but it is not recognized later as .gt $idleAfter . Thanks again.
    – Tfb9
    Jan 25, 2015 at 23:43
  • If you are trying to assign the value of a command ~/Documents/Seb/Prjcts/Idle/getidle/src/getIdle (aka command substitution) then I would suggest something like idleTimeMillis="$("$HOME/Documents/Seb/Prjcts/Idle/getidle/src/getIdle")" Jan 26, 2015 at 0:24
  • Yes, this perfect thanks! Now I'll try not to forget this lesson...
    – Tfb9
    Jan 26, 2015 at 1:24
  • I noticed Thunar (in the path string, top) does expand ~ in "~/Documents/", but does not expand $HOME in "$HOME/Documents"... at least for me.
    – Tfb9
    Feb 18, 2015 at 1:40
0

Tilde isn't expanded in quotes (single or double).

You have three options:

  1. remove the quotes:

    string="~/hello" -> string=~/hello (vulnerable to whitespace)

  2. use command substitution:

    string="~/hello" -> string="$(echo ~/hello)" (less vulnerable)

  3. as suggested by @steeldriver, use the HOME environment variable:

    string="~/hello" -> string="$HOME/hello"

1
  • 4. Change code for: idleTimeMillis=$(./getIdle) # doesn't need str_getIdle_exe variable
    – Tfb9
    Jan 25, 2015 at 23:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .