Handle filename with blank in shellscript

1

These are my folder structure.

[set symbolic links here]
/links/

[entity]    
/data/a 1/  #(folder name has blank)
/data/b 1/
/data/c 1/
/data/d 1/
.
.
.

I want to made symbolic link for each entities at once by shellscript.

for file in /data/*; do
    echo "${file}"
   ln -ds "/data/${file}" "/links/${file}"
done

However it shows the error like this.

/data/a 1
ln: failed to create symbolic link '/data//links/a 1': No such file or directory

I think is is relevant with blanks in folder name....???

How can I solve this??

whitebear

Posted 2018-06-27T03:29:59.603

Reputation: 273

Just put quotes around filename. ln -ds "/data/"${file}"" "/link/"${file}"". – C0deDaedalus – 2018-06-27T05:01:43.637

Answers

1

Are you sure it's /data//links/a 1 in the error message? I would expect /links//data/a 1

Blanks are not the issue. See what your echo gave you. Your $file already contains /data/ string. The piece of code

"/data/${file}" "/links/${file}"

adds /data/ or /links/ to a string where /data/ already is.

The easiest solution is to make $file not contain /data/ at all:

cd /data
for file in *; do
# the rest of your script
# in general remember you're in a different dir now

Alternatively you can keep for file in /data/*; and remove the excessive part later:

for file in /data/*; do
file=$(basename "$file")
# the rest of your script

The above solution will spawn multiple processes because basename is a separate executable. For this reason you may want the job to be done by the shell itself:

for file in /data/*; do
file="${file##*/}"
# the rest of your script

The syntax ${file##*/} prints $file but removes the longest string matching */ from the front of it. The effect is it gives you whatever there is after the last /.

Kamil Maciorowski

Posted 2018-06-27T03:29:59.603

Reputation: 38 429

I use cd at the head of script and it works!! thank you for your precise discription. I should be more carefully. – whitebear – 2018-06-27T08:13:28.667