Can't use folder path with tilde in rmdir - bash

I need to be able to remove a directory that is relative to the Documents folder of any user's system.
rmdir: ~/Documents/Folder: No such file or directory
If I manually enter the expanded path (/Users/ricky/Documents/Folder), it works fine.
I thought bash automatically expanded the tilde at the beginning of paths?
Update:
After trying a bunch of different approaches as recommended, I'm pretty confident now that the issue is with how I'm storing the path. I'm getting the path from a text file which I read line by line:
...
export_folder_path="$(echo $line | cut -f2 -d=)"
...
echo $export_folder_path
rmdir $export_folder_path
rmdir "$HOME/Documents/Folder\ 1"
This outputs the following:
$HOME/Documents/Folder\ 1
rmdir: $HOME/Documents/Folder\ 1: No such file or directory
rmdir: /Users/ricky/Documents/Folder\ 1: Directory not empty (This is actually what I want)
I can't work out what the difference between my manually typing the export path and using the variable. Why is the variable refusing to expand $HOME? I have tried many variations of adding quotations with no luck.

Tilde expansion doesn't work in all cases. You can instead use the HOME variable:
rmdir $HOME/Documents/Folder
From bash manual:
Tilde Expansion If a word begins with an unquoted tilde character
('~'), all of the characters preceding the first unquoted slash (or
all characters, if there is no unquoted slash) are considered a
tilde-prefix. If none of the characters in the tilde-prefix are
quoted, the characters in the tilde-prefix following the tilde are
treated as a possible login name. If this login name is the null
string, the tilde is replaced with the value of the shell parameter
HOME. If HOME is unset, the home directory of the user executing the
shell is substituted instead. Otherwise, the tilde-prefix is
replaced with the home directory associated with the specified login
name.
If the tilde-prefix is a '~+', the value of the shell variable PWD
replaces the tilde-prefix. If the tilde-prefix is a '~-', the value
of the shell variable OLDPWD, if it is set, is substituted. If the
characters following the tilde in the tilde-prefix consist of a
number N, optionally prefixed by a '+' or a '-', the tilde-prefix is
replaced with the corresponding element from the directory st, as it
would be displayed by the dirs builtin invoked with the tilde- prefix
as an argument. If the characters following the tilde in the
tilde-prefix consist of a number without a leading '+' or '-', '+' is
assumed.
If the login name is invalid, or the tilde expansion fails, the word
is unchanged.

Related

What does ~ stand for in a bash command line?

I know that ~ usually denotes my home directory. But I just accidentally issued
touch ~
and got a list of I don't know what:
~admin ~Debian-exim/ ~gnats ~messagebus/ ~postfix/ ~saned ~systemd-network/ ~xrdp etc...
What is this list? What does ~ stand for in this context?
Take a look at the man page for bash. There you will find a section called Tilde Expansion:
If a word begins with an unquoted tilde character (`~'), all of the characters preceding the first unquoted slash (or all characters, if there
is no unquoted slash) are considered a tilde-prefix. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-pre‐
fix following the tilde are treated as a possible login name.
So you probably got all your possible login names.

What does the path "//" mean?

I just found the direcory // on my machine and now i am wondering what it means.
user#dev:~$ cd /
user#dev:/$ pwd
/
user#dev:/$ cd //
user#dev://$ pwd
//
It is obvously the root directory, but when and why do i use the double slash instead of the single slash?
Is it related to the escaped path strings which i use while programming?
For example:
string path = "//home//user//foo.file"
I also tried it with zsh but it changes to the usual root directory /. So I think its bash specific.
This is part of the specification for Pathname Resolution:
A pathname consisting of a single <slash> shall resolve to the root directory of the process. A null pathname shall not be successfully resolved. If a pathname begins with two successive <slash> characters, the first component following the leading <slash> characters may be interpreted in an implementation-defined manner, although more than two leading <slash> characters shall be treated as a single <slash> character.
So your shell is just following the specification and leaving // alone as it might be implementationally defined as something other than /.

No such file or directory using a date variable in bash

Currently trying to write a Bash script to automatically create a .txt file with the name being today's date (Using NOW_FILE var), and then append today's date to that file (Using NOW_STRING var).
Attached is the script:
SAVE_PATH='~/Desktop/' # Set the save path
NOW_FILE=$(date +"%B_%d_%Y") # Date used for the file name
NOW_STRING=$(date +"%B %d %Y %r") # Date used within the entry
echo $NOW_STRING > $SAVE_PATH$NOW_FILE.txt # Output the date to the file
$EDITOR $SAVE_PATH$NOW_FILE.txt # Open the file with the default editor
If I execute the script, the error I get is:
~  echo $NOW_STRING > $SAVE_PATH$NOW_FILE.txt
-bash: ~/Desktop/March_08_2015.txt: No such file or directory
However, if I take the variables out, and directly execute the code sans vars, like this:
echo $(date +"%B %d %Y %r") > ~/Desktop/$(date +"%B_%d_%Y").txt
I have no problems appending the date to the file's first line.
I suck at Bash, so maybe I am missing something in my script, like not separating my variables from non-var strings..
Your problem is the ~ expansion. It's hot happening with your script as is.
SAVE_PATH="$HOME/Desktop/"
should do the trick. Make sure you quote that variable everywhere if the home path could contain whitespace (so quote it everywhere to be safe).
Alternatively, you can use:
SAVE_PATH=~/Desktop/
or
SAVE_PATH=~/"Some Path With Spaces/"
From the bash manual, §3.5.2 Tilde expansion:
If a word begins with an unquoted tilde character (‘~’), all of the characters up to the first unquoted slash (or all characters, if there is no unquoted slash) are considered a tilde-prefix. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible login name. If this login name is the null string, the tilde is replaced with the value of the HOME shell variable. If HOME is unset, the home directory of the user executing the shell is substituted instead. Otherwise, the tilde-prefix is replaced with the home directory associated with the specified login name.
[...] (info about ~+ and ~-)

When does the slash in a Linux path need to be outside quotes in a bash script

Why does the first expansion not work, yet the second does?
I know tilde has to be expanded outside quotes but the slash also had to be outside, unexpectedly.
#!/bin/bash
ls ~"/Documents/bashscripts/test.sh"
ls ~/"Documents/bashscripts/test.sh"
This is a subtlety in how tilde expansion works. In the second case, the tilde-followed-by-slash is expanded to the home directory of the current user. In the first case, the tilde-followed-by-quoted-word is attempted to be expanded to the home directory of the user named "/Documents/bashscripts/test.sh". From the manpage, Tilde Expansion section:
…all of the characters preceding the first unquoted slash are considered a tilde-prefix. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible login name. …

Bash path issue

I have a script which contains the following line:
propFile="${0%/*}/anteater.properties"
What does "${0%/*}" mean?
This command gives a path to the script - but there is a spaces at path and script can't find this file - how to deal with it?
The % operator in variable expansion removes the matching suffix pattern given to it. So ${0%/*} takes the variable $0, and removes all matching /* at the end. This is equivalent to the command dirname, which, when given a path, returns the parent directory of that path.
In order to deal with spaces in bash variable, whenever expanding the variable (i.e. whenever you write $var), you should quote it. In short, always use "$var" instead of just $var.
Consider reading shell parameter expansion and variable quoting in the bash manual to learn more about these two subjects.
strips the suffix matching /*, i.e. everything after last slash including the slash itself.
quote it wherever you use it (cat "$propFile").

Resources