Build a command dynamically

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
3
down vote

favorite












I'm working on a script and I need to build the tar command dynamically. I've been spending hours on this without being able to make it work... Bash and its string management is totally f'd up...



I've tried a looooooottttt of things, here are two examples to illustrate what I'm trying to do :



#!/bin/bash

TAR_ME="/tmp"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
_tar="tar "`printf -- '--exclude="%s" ' "$EXCLUDE[@]"`" -zcf tmp.tar.gz"
echo COMMAND: "$_tar"
$_tar "$TAR_ME"

echo -e "nnNEXT:nn"

EXCLUDE=("--exclude=/tmp/hello hello" "--exclude=/tmp/systemd*" "--exclude=/tmp/Temp*")
_tar="tar "`printf -- '%s ' "$EXCLUDE[@]"`" -zcf test.tar.gz"
echo COMMAND: "$_tar"
$_tar "$TAR_ME"


I want to be able to use _tar as a command, I've been able to make it work with classic path, but I need it to work with spaces in folders' name...
And every single time I got errors that look like :



COMMAND: tar --exclude="/tmp/hello hello" --exclude="/tmp/systemd*" --exclude="/tmp/Temp*" -zcf tmp.tar.gz /tmp
tar: hello": Cannot stat: No such file or directory

COMMAND: tar --exclude=/tmp/hello hello --exclude=/tmp/systemd* --exclude=/tmp/Temp* -zcf test.tar.gz
tar: hello: Cannot stat: No such file or directory


Just one thing you need to know, I need my script to work on very old machines, meaning I can't use last bash features...
I hope a bash genious will see my post because I've really been struggling on this one :(










share|improve this question









New contributor




ShellCode is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • I believe the --exclude option can only accept a single string after it. You can have multiple --exclude statements though. Maybe try "--exclude=/tmp/hello --exclude=hello" Oops. Nevermind. I misunderstood.
    – Lewis M
    1 hour ago











  • @LewisM I think OP want to exclude directory "/tmp/hello hello" (yes, with a space.
    – Archemar
    1 hour ago










  • @ShellCode what about quoting all exclude, e.g. "--exclude=/tmp/hello hello"
    – Archemar
    1 hour ago










  • Yeah. That's why I put the Oops statement later. :)
    – Lewis M
    1 hour ago










  • How about putting eval in front of the execution?
    – jimmij
    1 hour ago














up vote
3
down vote

favorite












I'm working on a script and I need to build the tar command dynamically. I've been spending hours on this without being able to make it work... Bash and its string management is totally f'd up...



I've tried a looooooottttt of things, here are two examples to illustrate what I'm trying to do :



#!/bin/bash

TAR_ME="/tmp"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
_tar="tar "`printf -- '--exclude="%s" ' "$EXCLUDE[@]"`" -zcf tmp.tar.gz"
echo COMMAND: "$_tar"
$_tar "$TAR_ME"

echo -e "nnNEXT:nn"

EXCLUDE=("--exclude=/tmp/hello hello" "--exclude=/tmp/systemd*" "--exclude=/tmp/Temp*")
_tar="tar "`printf -- '%s ' "$EXCLUDE[@]"`" -zcf test.tar.gz"
echo COMMAND: "$_tar"
$_tar "$TAR_ME"


I want to be able to use _tar as a command, I've been able to make it work with classic path, but I need it to work with spaces in folders' name...
And every single time I got errors that look like :



COMMAND: tar --exclude="/tmp/hello hello" --exclude="/tmp/systemd*" --exclude="/tmp/Temp*" -zcf tmp.tar.gz /tmp
tar: hello": Cannot stat: No such file or directory

COMMAND: tar --exclude=/tmp/hello hello --exclude=/tmp/systemd* --exclude=/tmp/Temp* -zcf test.tar.gz
tar: hello: Cannot stat: No such file or directory


Just one thing you need to know, I need my script to work on very old machines, meaning I can't use last bash features...
I hope a bash genious will see my post because I've really been struggling on this one :(










share|improve this question









New contributor




ShellCode is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • I believe the --exclude option can only accept a single string after it. You can have multiple --exclude statements though. Maybe try "--exclude=/tmp/hello --exclude=hello" Oops. Nevermind. I misunderstood.
    – Lewis M
    1 hour ago











  • @LewisM I think OP want to exclude directory "/tmp/hello hello" (yes, with a space.
    – Archemar
    1 hour ago










  • @ShellCode what about quoting all exclude, e.g. "--exclude=/tmp/hello hello"
    – Archemar
    1 hour ago










  • Yeah. That's why I put the Oops statement later. :)
    – Lewis M
    1 hour ago










  • How about putting eval in front of the execution?
    – jimmij
    1 hour ago












up vote
3
down vote

favorite









up vote
3
down vote

favorite











I'm working on a script and I need to build the tar command dynamically. I've been spending hours on this without being able to make it work... Bash and its string management is totally f'd up...



I've tried a looooooottttt of things, here are two examples to illustrate what I'm trying to do :



#!/bin/bash

TAR_ME="/tmp"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
_tar="tar "`printf -- '--exclude="%s" ' "$EXCLUDE[@]"`" -zcf tmp.tar.gz"
echo COMMAND: "$_tar"
$_tar "$TAR_ME"

echo -e "nnNEXT:nn"

EXCLUDE=("--exclude=/tmp/hello hello" "--exclude=/tmp/systemd*" "--exclude=/tmp/Temp*")
_tar="tar "`printf -- '%s ' "$EXCLUDE[@]"`" -zcf test.tar.gz"
echo COMMAND: "$_tar"
$_tar "$TAR_ME"


I want to be able to use _tar as a command, I've been able to make it work with classic path, but I need it to work with spaces in folders' name...
And every single time I got errors that look like :



COMMAND: tar --exclude="/tmp/hello hello" --exclude="/tmp/systemd*" --exclude="/tmp/Temp*" -zcf tmp.tar.gz /tmp
tar: hello": Cannot stat: No such file or directory

COMMAND: tar --exclude=/tmp/hello hello --exclude=/tmp/systemd* --exclude=/tmp/Temp* -zcf test.tar.gz
tar: hello: Cannot stat: No such file or directory


Just one thing you need to know, I need my script to work on very old machines, meaning I can't use last bash features...
I hope a bash genious will see my post because I've really been struggling on this one :(










share|improve this question









New contributor




ShellCode is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I'm working on a script and I need to build the tar command dynamically. I've been spending hours on this without being able to make it work... Bash and its string management is totally f'd up...



I've tried a looooooottttt of things, here are two examples to illustrate what I'm trying to do :



#!/bin/bash

TAR_ME="/tmp"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
_tar="tar "`printf -- '--exclude="%s" ' "$EXCLUDE[@]"`" -zcf tmp.tar.gz"
echo COMMAND: "$_tar"
$_tar "$TAR_ME"

echo -e "nnNEXT:nn"

EXCLUDE=("--exclude=/tmp/hello hello" "--exclude=/tmp/systemd*" "--exclude=/tmp/Temp*")
_tar="tar "`printf -- '%s ' "$EXCLUDE[@]"`" -zcf test.tar.gz"
echo COMMAND: "$_tar"
$_tar "$TAR_ME"


I want to be able to use _tar as a command, I've been able to make it work with classic path, but I need it to work with spaces in folders' name...
And every single time I got errors that look like :



COMMAND: tar --exclude="/tmp/hello hello" --exclude="/tmp/systemd*" --exclude="/tmp/Temp*" -zcf tmp.tar.gz /tmp
tar: hello": Cannot stat: No such file or directory

COMMAND: tar --exclude=/tmp/hello hello --exclude=/tmp/systemd* --exclude=/tmp/Temp* -zcf test.tar.gz
tar: hello: Cannot stat: No such file or directory


Just one thing you need to know, I need my script to work on very old machines, meaning I can't use last bash features...
I hope a bash genious will see my post because I've really been struggling on this one :(







bash shell-script tar string






share|improve this question









New contributor




ShellCode is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




ShellCode is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 52 mins ago





















New contributor




ShellCode is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 1 hour ago









ShellCode

1185




1185




New contributor




ShellCode is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





ShellCode is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






ShellCode is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











  • I believe the --exclude option can only accept a single string after it. You can have multiple --exclude statements though. Maybe try "--exclude=/tmp/hello --exclude=hello" Oops. Nevermind. I misunderstood.
    – Lewis M
    1 hour ago











  • @LewisM I think OP want to exclude directory "/tmp/hello hello" (yes, with a space.
    – Archemar
    1 hour ago










  • @ShellCode what about quoting all exclude, e.g. "--exclude=/tmp/hello hello"
    – Archemar
    1 hour ago










  • Yeah. That's why I put the Oops statement later. :)
    – Lewis M
    1 hour ago










  • How about putting eval in front of the execution?
    – jimmij
    1 hour ago
















  • I believe the --exclude option can only accept a single string after it. You can have multiple --exclude statements though. Maybe try "--exclude=/tmp/hello --exclude=hello" Oops. Nevermind. I misunderstood.
    – Lewis M
    1 hour ago











  • @LewisM I think OP want to exclude directory "/tmp/hello hello" (yes, with a space.
    – Archemar
    1 hour ago










  • @ShellCode what about quoting all exclude, e.g. "--exclude=/tmp/hello hello"
    – Archemar
    1 hour ago










  • Yeah. That's why I put the Oops statement later. :)
    – Lewis M
    1 hour ago










  • How about putting eval in front of the execution?
    – jimmij
    1 hour ago















I believe the --exclude option can only accept a single string after it. You can have multiple --exclude statements though. Maybe try "--exclude=/tmp/hello --exclude=hello" Oops. Nevermind. I misunderstood.
– Lewis M
1 hour ago





I believe the --exclude option can only accept a single string after it. You can have multiple --exclude statements though. Maybe try "--exclude=/tmp/hello --exclude=hello" Oops. Nevermind. I misunderstood.
– Lewis M
1 hour ago













@LewisM I think OP want to exclude directory "/tmp/hello hello" (yes, with a space.
– Archemar
1 hour ago




@LewisM I think OP want to exclude directory "/tmp/hello hello" (yes, with a space.
– Archemar
1 hour ago












@ShellCode what about quoting all exclude, e.g. "--exclude=/tmp/hello hello"
– Archemar
1 hour ago




@ShellCode what about quoting all exclude, e.g. "--exclude=/tmp/hello hello"
– Archemar
1 hour ago












Yeah. That's why I put the Oops statement later. :)
– Lewis M
1 hour ago




Yeah. That's why I put the Oops statement later. :)
– Lewis M
1 hour ago












How about putting eval in front of the execution?
– jimmij
1 hour ago




How about putting eval in front of the execution?
– jimmij
1 hour ago










2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










Don't try to make an executable string. Instead build the arguments in an array and use that when calling tar (you are already using an array properly for EXCLUDE):



#!/bin/bash

directory=/tmp

exclude=( "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*" )

# Now build the list of "--exclude" options from the exclude array:
for elem in "$exclude[@]"; do
exclude_opts+=( --exclude="$elem" )
done

# Run tar
tar -cz -f tmp.tar.gz "$exclude_opts[@]" "$directory"


With /bin/sh:



#!/bin/sh

directory=/tmp

set -- "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

# Now build the list of "--exclude" options from the $@ array:
for elem do
shift
set -- "$@" --exclude="$elem"
done

# Run tar
tar -cz -f tmp.tar.gz "$@" "$directory"


Note the quoting of $@ in the sh code and of both $exclude[@] and $exclude_opts[@] in the bash code. This ensures that the lists are expanded to individually quoted elements.



Related:



  • How can we run a command stored in a variable?





share|improve this answer






















  • Had to adapt your bash script a little bit to my needs, but it works like a charm ! :) Thank you !
    – ShellCode
    11 mins ago

















up vote
1
down vote













mix()
p=$1; shift; q=$1; shift; c=
i=1; for a; do c="$c $q "$$i""; i=$((i+1)); done
eval "$p%%*$c$p#*%"

mix 'tar % -zcf tmp.tar.gz' --exclude "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
mix 'tar % -zcf tmp.tar.gz' --exclude "$EXCLUDE[@]"


Extending the answer here.
This doesn't rely on any bashisms, it will also work fine with debian's /bin/sh, and with busybox.






share|improve this answer






















  • Thank you very much for your help, but I don't really like the eval, it's quite dangerous... Moreover, this code is quite hard to understand, don't you have something easier ? :/ The script will be distributed so I have to keep it as simple as possible...
    – ShellCode
    52 mins ago










  • It's not dangerous. Run it with set -x. What exactly you don't understand?
    – mosvy
    51 mins ago










  • Also, read the original answer on stackoverflow. It includes a demo.
    – mosvy
    46 mins ago










  • It works quite well though... Waiting to see if anybody has a cleaner answer, otherwise I will accept yours. Maybe there is nothing wrong with that code, but every time I see an eval, I'm afraid the code could lead to command injection, that's why I try to avoid it
    – ShellCode
    43 mins ago











  • I've updated the answer with a fix for indexes > 9. You can replace the eval with an echo to see what's actually getting (the eval doesn't see the filenames)
    – mosvy
    26 mins ago










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);






ShellCode is a new contributor. Be nice, and check out our Code of Conduct.









 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f473241%2fbuild-a-command-dynamically%23new-answer', 'question_page');

);

Post as a guest






























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
3
down vote



accepted










Don't try to make an executable string. Instead build the arguments in an array and use that when calling tar (you are already using an array properly for EXCLUDE):



#!/bin/bash

directory=/tmp

exclude=( "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*" )

# Now build the list of "--exclude" options from the exclude array:
for elem in "$exclude[@]"; do
exclude_opts+=( --exclude="$elem" )
done

# Run tar
tar -cz -f tmp.tar.gz "$exclude_opts[@]" "$directory"


With /bin/sh:



#!/bin/sh

directory=/tmp

set -- "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

# Now build the list of "--exclude" options from the $@ array:
for elem do
shift
set -- "$@" --exclude="$elem"
done

# Run tar
tar -cz -f tmp.tar.gz "$@" "$directory"


Note the quoting of $@ in the sh code and of both $exclude[@] and $exclude_opts[@] in the bash code. This ensures that the lists are expanded to individually quoted elements.



Related:



  • How can we run a command stored in a variable?





share|improve this answer






















  • Had to adapt your bash script a little bit to my needs, but it works like a charm ! :) Thank you !
    – ShellCode
    11 mins ago














up vote
3
down vote



accepted










Don't try to make an executable string. Instead build the arguments in an array and use that when calling tar (you are already using an array properly for EXCLUDE):



#!/bin/bash

directory=/tmp

exclude=( "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*" )

# Now build the list of "--exclude" options from the exclude array:
for elem in "$exclude[@]"; do
exclude_opts+=( --exclude="$elem" )
done

# Run tar
tar -cz -f tmp.tar.gz "$exclude_opts[@]" "$directory"


With /bin/sh:



#!/bin/sh

directory=/tmp

set -- "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

# Now build the list of "--exclude" options from the $@ array:
for elem do
shift
set -- "$@" --exclude="$elem"
done

# Run tar
tar -cz -f tmp.tar.gz "$@" "$directory"


Note the quoting of $@ in the sh code and of both $exclude[@] and $exclude_opts[@] in the bash code. This ensures that the lists are expanded to individually quoted elements.



Related:



  • How can we run a command stored in a variable?





share|improve this answer






















  • Had to adapt your bash script a little bit to my needs, but it works like a charm ! :) Thank you !
    – ShellCode
    11 mins ago












up vote
3
down vote



accepted







up vote
3
down vote



accepted






Don't try to make an executable string. Instead build the arguments in an array and use that when calling tar (you are already using an array properly for EXCLUDE):



#!/bin/bash

directory=/tmp

exclude=( "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*" )

# Now build the list of "--exclude" options from the exclude array:
for elem in "$exclude[@]"; do
exclude_opts+=( --exclude="$elem" )
done

# Run tar
tar -cz -f tmp.tar.gz "$exclude_opts[@]" "$directory"


With /bin/sh:



#!/bin/sh

directory=/tmp

set -- "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

# Now build the list of "--exclude" options from the $@ array:
for elem do
shift
set -- "$@" --exclude="$elem"
done

# Run tar
tar -cz -f tmp.tar.gz "$@" "$directory"


Note the quoting of $@ in the sh code and of both $exclude[@] and $exclude_opts[@] in the bash code. This ensures that the lists are expanded to individually quoted elements.



Related:



  • How can we run a command stored in a variable?





share|improve this answer














Don't try to make an executable string. Instead build the arguments in an array and use that when calling tar (you are already using an array properly for EXCLUDE):



#!/bin/bash

directory=/tmp

exclude=( "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*" )

# Now build the list of "--exclude" options from the exclude array:
for elem in "$exclude[@]"; do
exclude_opts+=( --exclude="$elem" )
done

# Run tar
tar -cz -f tmp.tar.gz "$exclude_opts[@]" "$directory"


With /bin/sh:



#!/bin/sh

directory=/tmp

set -- "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

# Now build the list of "--exclude" options from the $@ array:
for elem do
shift
set -- "$@" --exclude="$elem"
done

# Run tar
tar -cz -f tmp.tar.gz "$@" "$directory"


Note the quoting of $@ in the sh code and of both $exclude[@] and $exclude_opts[@] in the bash code. This ensures that the lists are expanded to individually quoted elements.



Related:



  • How can we run a command stored in a variable?






share|improve this answer














share|improve this answer



share|improve this answer








edited 28 mins ago

























answered 42 mins ago









Kusalananda

108k14209332




108k14209332











  • Had to adapt your bash script a little bit to my needs, but it works like a charm ! :) Thank you !
    – ShellCode
    11 mins ago
















  • Had to adapt your bash script a little bit to my needs, but it works like a charm ! :) Thank you !
    – ShellCode
    11 mins ago















Had to adapt your bash script a little bit to my needs, but it works like a charm ! :) Thank you !
– ShellCode
11 mins ago




Had to adapt your bash script a little bit to my needs, but it works like a charm ! :) Thank you !
– ShellCode
11 mins ago












up vote
1
down vote













mix()
p=$1; shift; q=$1; shift; c=
i=1; for a; do c="$c $q "$$i""; i=$((i+1)); done
eval "$p%%*$c$p#*%"

mix 'tar % -zcf tmp.tar.gz' --exclude "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
mix 'tar % -zcf tmp.tar.gz' --exclude "$EXCLUDE[@]"


Extending the answer here.
This doesn't rely on any bashisms, it will also work fine with debian's /bin/sh, and with busybox.






share|improve this answer






















  • Thank you very much for your help, but I don't really like the eval, it's quite dangerous... Moreover, this code is quite hard to understand, don't you have something easier ? :/ The script will be distributed so I have to keep it as simple as possible...
    – ShellCode
    52 mins ago










  • It's not dangerous. Run it with set -x. What exactly you don't understand?
    – mosvy
    51 mins ago










  • Also, read the original answer on stackoverflow. It includes a demo.
    – mosvy
    46 mins ago










  • It works quite well though... Waiting to see if anybody has a cleaner answer, otherwise I will accept yours. Maybe there is nothing wrong with that code, but every time I see an eval, I'm afraid the code could lead to command injection, that's why I try to avoid it
    – ShellCode
    43 mins ago











  • I've updated the answer with a fix for indexes > 9. You can replace the eval with an echo to see what's actually getting (the eval doesn't see the filenames)
    – mosvy
    26 mins ago














up vote
1
down vote













mix()
p=$1; shift; q=$1; shift; c=
i=1; for a; do c="$c $q "$$i""; i=$((i+1)); done
eval "$p%%*$c$p#*%"

mix 'tar % -zcf tmp.tar.gz' --exclude "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
mix 'tar % -zcf tmp.tar.gz' --exclude "$EXCLUDE[@]"


Extending the answer here.
This doesn't rely on any bashisms, it will also work fine with debian's /bin/sh, and with busybox.






share|improve this answer






















  • Thank you very much for your help, but I don't really like the eval, it's quite dangerous... Moreover, this code is quite hard to understand, don't you have something easier ? :/ The script will be distributed so I have to keep it as simple as possible...
    – ShellCode
    52 mins ago










  • It's not dangerous. Run it with set -x. What exactly you don't understand?
    – mosvy
    51 mins ago










  • Also, read the original answer on stackoverflow. It includes a demo.
    – mosvy
    46 mins ago










  • It works quite well though... Waiting to see if anybody has a cleaner answer, otherwise I will accept yours. Maybe there is nothing wrong with that code, but every time I see an eval, I'm afraid the code could lead to command injection, that's why I try to avoid it
    – ShellCode
    43 mins ago











  • I've updated the answer with a fix for indexes > 9. You can replace the eval with an echo to see what's actually getting (the eval doesn't see the filenames)
    – mosvy
    26 mins ago












up vote
1
down vote










up vote
1
down vote









mix()
p=$1; shift; q=$1; shift; c=
i=1; for a; do c="$c $q "$$i""; i=$((i+1)); done
eval "$p%%*$c$p#*%"

mix 'tar % -zcf tmp.tar.gz' --exclude "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
mix 'tar % -zcf tmp.tar.gz' --exclude "$EXCLUDE[@]"


Extending the answer here.
This doesn't rely on any bashisms, it will also work fine with debian's /bin/sh, and with busybox.






share|improve this answer














mix()
p=$1; shift; q=$1; shift; c=
i=1; for a; do c="$c $q "$$i""; i=$((i+1)); done
eval "$p%%*$c$p#*%"

mix 'tar % -zcf tmp.tar.gz' --exclude "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
mix 'tar % -zcf tmp.tar.gz' --exclude "$EXCLUDE[@]"


Extending the answer here.
This doesn't rely on any bashisms, it will also work fine with debian's /bin/sh, and with busybox.







share|improve this answer














share|improve this answer



share|improve this answer








edited 22 mins ago

























answered 1 hour ago









mosvy

1,772110




1,772110











  • Thank you very much for your help, but I don't really like the eval, it's quite dangerous... Moreover, this code is quite hard to understand, don't you have something easier ? :/ The script will be distributed so I have to keep it as simple as possible...
    – ShellCode
    52 mins ago










  • It's not dangerous. Run it with set -x. What exactly you don't understand?
    – mosvy
    51 mins ago










  • Also, read the original answer on stackoverflow. It includes a demo.
    – mosvy
    46 mins ago










  • It works quite well though... Waiting to see if anybody has a cleaner answer, otherwise I will accept yours. Maybe there is nothing wrong with that code, but every time I see an eval, I'm afraid the code could lead to command injection, that's why I try to avoid it
    – ShellCode
    43 mins ago











  • I've updated the answer with a fix for indexes > 9. You can replace the eval with an echo to see what's actually getting (the eval doesn't see the filenames)
    – mosvy
    26 mins ago
















  • Thank you very much for your help, but I don't really like the eval, it's quite dangerous... Moreover, this code is quite hard to understand, don't you have something easier ? :/ The script will be distributed so I have to keep it as simple as possible...
    – ShellCode
    52 mins ago










  • It's not dangerous. Run it with set -x. What exactly you don't understand?
    – mosvy
    51 mins ago










  • Also, read the original answer on stackoverflow. It includes a demo.
    – mosvy
    46 mins ago










  • It works quite well though... Waiting to see if anybody has a cleaner answer, otherwise I will accept yours. Maybe there is nothing wrong with that code, but every time I see an eval, I'm afraid the code could lead to command injection, that's why I try to avoid it
    – ShellCode
    43 mins ago











  • I've updated the answer with a fix for indexes > 9. You can replace the eval with an echo to see what's actually getting (the eval doesn't see the filenames)
    – mosvy
    26 mins ago















Thank you very much for your help, but I don't really like the eval, it's quite dangerous... Moreover, this code is quite hard to understand, don't you have something easier ? :/ The script will be distributed so I have to keep it as simple as possible...
– ShellCode
52 mins ago




Thank you very much for your help, but I don't really like the eval, it's quite dangerous... Moreover, this code is quite hard to understand, don't you have something easier ? :/ The script will be distributed so I have to keep it as simple as possible...
– ShellCode
52 mins ago












It's not dangerous. Run it with set -x. What exactly you don't understand?
– mosvy
51 mins ago




It's not dangerous. Run it with set -x. What exactly you don't understand?
– mosvy
51 mins ago












Also, read the original answer on stackoverflow. It includes a demo.
– mosvy
46 mins ago




Also, read the original answer on stackoverflow. It includes a demo.
– mosvy
46 mins ago












It works quite well though... Waiting to see if anybody has a cleaner answer, otherwise I will accept yours. Maybe there is nothing wrong with that code, but every time I see an eval, I'm afraid the code could lead to command injection, that's why I try to avoid it
– ShellCode
43 mins ago





It works quite well though... Waiting to see if anybody has a cleaner answer, otherwise I will accept yours. Maybe there is nothing wrong with that code, but every time I see an eval, I'm afraid the code could lead to command injection, that's why I try to avoid it
– ShellCode
43 mins ago













I've updated the answer with a fix for indexes > 9. You can replace the eval with an echo to see what's actually getting (the eval doesn't see the filenames)
– mosvy
26 mins ago




I've updated the answer with a fix for indexes > 9. You can replace the eval with an echo to see what's actually getting (the eval doesn't see the filenames)
– mosvy
26 mins ago










ShellCode is a new contributor. Be nice, and check out our Code of Conduct.









 

draft saved


draft discarded


















ShellCode is a new contributor. Be nice, and check out our Code of Conduct.












ShellCode is a new contributor. Be nice, and check out our Code of Conduct.











ShellCode is a new contributor. Be nice, and check out our Code of Conduct.













 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f473241%2fbuild-a-command-dynamically%23new-answer', 'question_page');

);

Post as a guest













































































Comments

Popular posts from this blog

What does second last employer means? [closed]

Installing NextGIS Connect into QGIS 3?

One-line joke