How to have a script work with “$@” or a default list of parameters while not breaking paths with...
I want a script that will run another utility over some default paths if no parameters are passed to it; ideally I want this safe for paths that contain spaces.
So far I have script.sh
:
#!/bin/sh
base=$(dirname "$0")
exec touch "${@:-"$base/aaa" "$base/bbb"}"
If I put this into a folder called "foo bar" and run it as:
foo bar/script.sh
I want it to should end up doing:
touch foo bar/aaa foo bar/bbb
i.e. create files "aaa" and "bbb" under "foo bar", the directory in which the script is located.
Instead I get the error
touch: cannot touch 'foo bar/aaa foo bar/bbb': No such file or directory
(If I pass in parameters to the script it seems to work fine. Presumably removing the outer quotes in the last command would reverse my cases.)
shell-script arguments
add a comment |
I want a script that will run another utility over some default paths if no parameters are passed to it; ideally I want this safe for paths that contain spaces.
So far I have script.sh
:
#!/bin/sh
base=$(dirname "$0")
exec touch "${@:-"$base/aaa" "$base/bbb"}"
If I put this into a folder called "foo bar" and run it as:
foo bar/script.sh
I want it to should end up doing:
touch foo bar/aaa foo bar/bbb
i.e. create files "aaa" and "bbb" under "foo bar", the directory in which the script is located.
Instead I get the error
touch: cannot touch 'foo bar/aaa foo bar/bbb': No such file or directory
(If I pass in parameters to the script it seems to work fine. Presumably removing the outer quotes in the last command would reverse my cases.)
shell-script arguments
add a comment |
I want a script that will run another utility over some default paths if no parameters are passed to it; ideally I want this safe for paths that contain spaces.
So far I have script.sh
:
#!/bin/sh
base=$(dirname "$0")
exec touch "${@:-"$base/aaa" "$base/bbb"}"
If I put this into a folder called "foo bar" and run it as:
foo bar/script.sh
I want it to should end up doing:
touch foo bar/aaa foo bar/bbb
i.e. create files "aaa" and "bbb" under "foo bar", the directory in which the script is located.
Instead I get the error
touch: cannot touch 'foo bar/aaa foo bar/bbb': No such file or directory
(If I pass in parameters to the script it seems to work fine. Presumably removing the outer quotes in the last command would reverse my cases.)
shell-script arguments
I want a script that will run another utility over some default paths if no parameters are passed to it; ideally I want this safe for paths that contain spaces.
So far I have script.sh
:
#!/bin/sh
base=$(dirname "$0")
exec touch "${@:-"$base/aaa" "$base/bbb"}"
If I put this into a folder called "foo bar" and run it as:
foo bar/script.sh
I want it to should end up doing:
touch foo bar/aaa foo bar/bbb
i.e. create files "aaa" and "bbb" under "foo bar", the directory in which the script is located.
Instead I get the error
touch: cannot touch 'foo bar/aaa foo bar/bbb': No such file or directory
(If I pass in parameters to the script it seems to work fine. Presumably removing the outer quotes in the last command would reverse my cases.)
shell-script arguments
shell-script arguments
edited 4 hours ago
Gilles
530k12810631591
530k12810631591
asked 4 hours ago
millimoosemillimoose
24315
24315
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
It appears you can't set default parameters in an expansion of ${@:-...}
, and "${@:-"$base/aaa" "$base/bbb"}"
is expanded as a single string.
If you want to set default parameters you might want to do this:
base=$(dirname -- "$0")
# test explicitly for no parameters, and set them.
if [ "$#" -eq 0 ]; then
set -- "$base/aaa" "$base/bbb"
fi
Then, the "$@"
magically quoted parameter substitution can happen unabated:
touch -- "$@"
1
OP is using/bin/sh
so maybeif ((!$#)); then
orif [ $# -eq 0 ]; then
?
– Jesse_b
4 hours ago
1
@Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me
– millimoose
4 hours ago
1
(I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)
– millimoose
4 hours ago
About that first sentence,set --; echo ${@:-default}; set -- a b; echo ${@:-default};
works (i.e. printsdefault
and thena b
) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.
– ilkkachu
4 hours ago
1
Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer
– Isaac
3 hours ago
|
show 1 more comment
It IS possible to use several parameters in a default expansion ${@-...}
,
like this:
#!/bin/bash
base=$(dirname "$0")
arr=("$base/aaa" "$base/bbb")
touch "${@:-"${arr[@]}"}"
But only on shells that have arrays (ksh, zsh, bash, etc.).
add a comment |
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',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f493980%2fhow-to-have-a-script-work-with-or-a-default-list-of-parameters-while-not-br%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
It appears you can't set default parameters in an expansion of ${@:-...}
, and "${@:-"$base/aaa" "$base/bbb"}"
is expanded as a single string.
If you want to set default parameters you might want to do this:
base=$(dirname -- "$0")
# test explicitly for no parameters, and set them.
if [ "$#" -eq 0 ]; then
set -- "$base/aaa" "$base/bbb"
fi
Then, the "$@"
magically quoted parameter substitution can happen unabated:
touch -- "$@"
1
OP is using/bin/sh
so maybeif ((!$#)); then
orif [ $# -eq 0 ]; then
?
– Jesse_b
4 hours ago
1
@Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me
– millimoose
4 hours ago
1
(I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)
– millimoose
4 hours ago
About that first sentence,set --; echo ${@:-default}; set -- a b; echo ${@:-default};
works (i.e. printsdefault
and thena b
) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.
– ilkkachu
4 hours ago
1
Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer
– Isaac
3 hours ago
|
show 1 more comment
It appears you can't set default parameters in an expansion of ${@:-...}
, and "${@:-"$base/aaa" "$base/bbb"}"
is expanded as a single string.
If you want to set default parameters you might want to do this:
base=$(dirname -- "$0")
# test explicitly for no parameters, and set them.
if [ "$#" -eq 0 ]; then
set -- "$base/aaa" "$base/bbb"
fi
Then, the "$@"
magically quoted parameter substitution can happen unabated:
touch -- "$@"
1
OP is using/bin/sh
so maybeif ((!$#)); then
orif [ $# -eq 0 ]; then
?
– Jesse_b
4 hours ago
1
@Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me
– millimoose
4 hours ago
1
(I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)
– millimoose
4 hours ago
About that first sentence,set --; echo ${@:-default}; set -- a b; echo ${@:-default};
works (i.e. printsdefault
and thena b
) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.
– ilkkachu
4 hours ago
1
Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer
– Isaac
3 hours ago
|
show 1 more comment
It appears you can't set default parameters in an expansion of ${@:-...}
, and "${@:-"$base/aaa" "$base/bbb"}"
is expanded as a single string.
If you want to set default parameters you might want to do this:
base=$(dirname -- "$0")
# test explicitly for no parameters, and set them.
if [ "$#" -eq 0 ]; then
set -- "$base/aaa" "$base/bbb"
fi
Then, the "$@"
magically quoted parameter substitution can happen unabated:
touch -- "$@"
It appears you can't set default parameters in an expansion of ${@:-...}
, and "${@:-"$base/aaa" "$base/bbb"}"
is expanded as a single string.
If you want to set default parameters you might want to do this:
base=$(dirname -- "$0")
# test explicitly for no parameters, and set them.
if [ "$#" -eq 0 ]; then
set -- "$base/aaa" "$base/bbb"
fi
Then, the "$@"
magically quoted parameter substitution can happen unabated:
touch -- "$@"
edited 4 hours ago
Stéphane Chazelas
300k54564916
300k54564916
answered 4 hours ago
glenn jackmanglenn jackman
50.6k570108
50.6k570108
1
OP is using/bin/sh
so maybeif ((!$#)); then
orif [ $# -eq 0 ]; then
?
– Jesse_b
4 hours ago
1
@Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me
– millimoose
4 hours ago
1
(I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)
– millimoose
4 hours ago
About that first sentence,set --; echo ${@:-default}; set -- a b; echo ${@:-default};
works (i.e. printsdefault
and thena b
) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.
– ilkkachu
4 hours ago
1
Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer
– Isaac
3 hours ago
|
show 1 more comment
1
OP is using/bin/sh
so maybeif ((!$#)); then
orif [ $# -eq 0 ]; then
?
– Jesse_b
4 hours ago
1
@Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me
– millimoose
4 hours ago
1
(I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)
– millimoose
4 hours ago
About that first sentence,set --; echo ${@:-default}; set -- a b; echo ${@:-default};
works (i.e. printsdefault
and thena b
) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.
– ilkkachu
4 hours ago
1
Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer
– Isaac
3 hours ago
1
1
OP is using
/bin/sh
so maybe if ((!$#)); then
or if [ $# -eq 0 ]; then
?– Jesse_b
4 hours ago
OP is using
/bin/sh
so maybe if ((!$#)); then
or if [ $# -eq 0 ]; then
?– Jesse_b
4 hours ago
1
1
@Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me
– millimoose
4 hours ago
@Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me
– millimoose
4 hours ago
1
1
(I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)
– millimoose
4 hours ago
(I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)
– millimoose
4 hours ago
About that first sentence,
set --; echo ${@:-default}; set -- a b; echo ${@:-default};
works (i.e. prints default
and then a b
) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.– ilkkachu
4 hours ago
About that first sentence,
set --; echo ${@:-default}; set -- a b; echo ${@:-default};
works (i.e. prints default
and then a b
) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.– ilkkachu
4 hours ago
1
1
Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer
– Isaac
3 hours ago
Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer
– Isaac
3 hours ago
|
show 1 more comment
It IS possible to use several parameters in a default expansion ${@-...}
,
like this:
#!/bin/bash
base=$(dirname "$0")
arr=("$base/aaa" "$base/bbb")
touch "${@:-"${arr[@]}"}"
But only on shells that have arrays (ksh, zsh, bash, etc.).
add a comment |
It IS possible to use several parameters in a default expansion ${@-...}
,
like this:
#!/bin/bash
base=$(dirname "$0")
arr=("$base/aaa" "$base/bbb")
touch "${@:-"${arr[@]}"}"
But only on shells that have arrays (ksh, zsh, bash, etc.).
add a comment |
It IS possible to use several parameters in a default expansion ${@-...}
,
like this:
#!/bin/bash
base=$(dirname "$0")
arr=("$base/aaa" "$base/bbb")
touch "${@:-"${arr[@]}"}"
But only on shells that have arrays (ksh, zsh, bash, etc.).
It IS possible to use several parameters in a default expansion ${@-...}
,
like this:
#!/bin/bash
base=$(dirname "$0")
arr=("$base/aaa" "$base/bbb")
touch "${@:-"${arr[@]}"}"
But only on shells that have arrays (ksh, zsh, bash, etc.).
edited 2 hours ago
Wildcard
22.7k962164
22.7k962164
answered 3 hours ago
IsaacIsaac
11.4k11652
11.4k11652
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f493980%2fhow-to-have-a-script-work-with-or-a-default-list-of-parameters-while-not-br%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown