8ToThePowerOfMol
8ToThePowerOfMol

Reputation: 91

Cannot tar array of files with spaces inside filename inside bash script

I have bash script my_tar.sh which calls tar czf output.tgz on 3 files with filename spaces passed from array: file, file 2 and file 3.

#!/bin/bash

declare -a files_to_zip

files_to_zip+=(\'file\')
files_to_zip+=(\'file 2\')
files_to_zip+=(\'file 3\')

echo "tar czf output.tgz "${files_to_zip[*]}""
tar czf output.tgz "${files_to_zip[*]}" || echo "ERROR"

Though three files exist, when tar is ran inside the script, it ends with error. However when I literally run echo output (which is the same as next command of my_tar.sh) inside bash console, tar runs ok:

$ ls
file  file 2  file 3  my_tar.sh
$ ./my_tar.sh
tar czf output.tgz 'file' 'file 2' 'file 3'
tar: 'file' 'file 2' 'file 3': Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
ERROR
$ tar czf output.tgz 'file' 'file 2' 'file 3'
$ 

Any ideas?

Upvotes: 2

Views: 1035

Answers (2)

Kronen_75
Kronen_75

Reputation: 1

I had the problem to tar and compress many directories, files and programs on a MacOS system and make it work by decompressing all of those files on another computer. I don't know if it will help, but, after many tests I did it. Here is the script that I used, and it worked fine to deal with spaces on folders, .app and every thing. I had to add doble doble quotes and also quotes to the vars: This compress and bzip2 it all. Maybe can help some one.

#!/bin/bash

## Routes
epic=""/Applications/Epic\ Games\ Launcher.app""
urshared=""/Users/Shared/Epic\ Games""
wwise=""/Applications/Wwise\ Launcher.app""
ww1170=""/Applications/Audiokinetic/Wwise\ 2022.1.7.8290""
ww1171=""/Library/Application\ Support/Audiokinetic/Wwise\ 2022.1.7.8290""
ww202=""/Applications/Audiokinetic/Wwise\ 2022.1.4.8202""
ww202b=""/Library/Application\ Support/Audiokinetic/Wwise\ 2022.1.4.8202""
libframe=""/Library/Frameworks""
advgame=""/Applications/Audiokinetic/Wwise\ Adventure\ Game\ 2022.1.0.230""
unityhub=""/Applications/Unity\ Hub.app""
uniyed2018=""/Applications/Unity/Hub/Editor/2018.4.17f1""
unityed2020=""/Applications/Unity/Hub/Editor/2020.3.40f1""
fmod=""/Applications/FMOD\ Studio.app""

tar -cjf franza.tgz "$epic" "$urshared" "$wwise" "$ww1170" "$ww1171" "$ww202" "$ww202b" "$libframe" "$advgame" "$unityhub" "$uniyed2018" "$unityed2020" "$fmod"

Upvotes: 0

Jarodiv
Jarodiv

Reputation: 146

The problem is, that you escape the ' and thereby add it to the file name instead of using it to quote the string:

files_to_zip+=(\'file 2\')

vs

files_to_zip+=( 'file 2' )

Also, it generally is advisable to use @ instead of the asterisk (*) to reference all array elements, since the asterisk will not be interpreted when quoted (-> http://tldp.org/LDP/abs/html/arrays.html, Example 27-7) .

Also also I assume your intention was to put quotes in the string when printing out the array elements. To do so, you need to escape the quotes.

echo "tar czf output.tgz \"${files_to_zip[@]}\""

Your fixed script would look like

#!/bin/bash

declare -a files_to_zip

files_to_zip+=( 'file' )
files_to_zip+=( 'file 2' )
files_to_zip+=( 'file 3' )

echo "tar czf output.tgz \"${files_to_zip[@]}\""
tar czf output.tgz "${files_to_zip[@]}" || echo "ERROR"

Upvotes: 3

Related Questions