Could PATH contain newlines?
It is known that a path could contain newlines in any of its components.
Should we conclude then that the environment variable $PATH
could contain newlines ?
If so, how to split the $PATH
into its elements, similar to (Bourne like):
IFS=':' ; set -f
for var in $PATH
do
echo "<$var>"
done
But if it could be done without changing IFS, even better.
shell path newlines
add a comment |
It is known that a path could contain newlines in any of its components.
Should we conclude then that the environment variable $PATH
could contain newlines ?
If so, how to split the $PATH
into its elements, similar to (Bourne like):
IFS=':' ; set -f
for var in $PATH
do
echo "<$var>"
done
But if it could be done without changing IFS, even better.
shell path newlines
Note that in the Bourne shell (contrary to POSIX shells),/bin::/usr/bin
would be split into/bin
and/usr/bin
instead of/bin
,""
and/usr/bin
.
– Stéphane Chazelas
20 mins ago
add a comment |
It is known that a path could contain newlines in any of its components.
Should we conclude then that the environment variable $PATH
could contain newlines ?
If so, how to split the $PATH
into its elements, similar to (Bourne like):
IFS=':' ; set -f
for var in $PATH
do
echo "<$var>"
done
But if it could be done without changing IFS, even better.
shell path newlines
It is known that a path could contain newlines in any of its components.
Should we conclude then that the environment variable $PATH
could contain newlines ?
If so, how to split the $PATH
into its elements, similar to (Bourne like):
IFS=':' ; set -f
for var in $PATH
do
echo "<$var>"
done
But if it could be done without changing IFS, even better.
shell path newlines
shell path newlines
edited 53 mins ago
ilkkachu
55.9k784155
55.9k784155
asked 4 hours ago
Isaac
11.2k11648
11.2k11648
Note that in the Bourne shell (contrary to POSIX shells),/bin::/usr/bin
would be split into/bin
and/usr/bin
instead of/bin
,""
and/usr/bin
.
– Stéphane Chazelas
20 mins ago
add a comment |
Note that in the Bourne shell (contrary to POSIX shells),/bin::/usr/bin
would be split into/bin
and/usr/bin
instead of/bin
,""
and/usr/bin
.
– Stéphane Chazelas
20 mins ago
Note that in the Bourne shell (contrary to POSIX shells),
/bin::/usr/bin
would be split into /bin
and /usr/bin
instead of /bin
, ""
and /usr/bin
.– Stéphane Chazelas
20 mins ago
Note that in the Bourne shell (contrary to POSIX shells),
/bin::/usr/bin
would be split into /bin
and /usr/bin
instead of /bin
, ""
and /usr/bin
.– Stéphane Chazelas
20 mins ago
add a comment |
2 Answers
2
active
oldest
votes
Yes, PATH
can contain newlines (even on ancient Unix system).
As to splitting any string in shell, the only way you can do it portably is with IFS
. You can use IFS=:; set -f -- $PATH
or pass it to a function instead of looping with for
, though.
With bash
you can "read" a string into an array (mapfile -td: <<< "$PATH" path
). But using arrays is usually not a good idea, because they can't be stored transparently in environment variables or passed as a single argument to external commands.
Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
– ilkkachu
1 hour ago
No, you need theset -f
to take effect before the$PATH
expansion. So it should beset -o noglob; set -- $PATH""
– Stéphane Chazelas
51 mins ago
Thatmapfile -td: <<< "$PATH"
adds a trailing newline to the last element (and needs bash 4.4 or above).
– Stéphane Chazelas
51 mins ago
add a comment |
In POSIX shells, $IFS
is a field delimiter, not separator, so a $PATH
value like /bin:/usr/bin:
would be split into /bin
and /usr/bin
instead of /bin
, /usr/bin
and the empty string (meaning the current directory). You need:
IFS=:; set -o noglob
for var in $PATH""; do
printf '<%s>n' "$var"
done
To avoid modifying global settings, you can use a shell with explicit splitting operators like zsh
:
for var in "${(s/:/@)PATH}"; do
printf '<%s>n' "$var"
done
Though in that case, zsh
already has the $path
array tied to $PATH
like in csh
/tcsh
, so:
for var in "$path[@]"; do
printf '<%s>n' "$var"
done
In any case, yes, in theory $PATH
like any variable could contain newline characters, the newline character is not special in any way when it comes to file path resolution. I don't expect anyone sensible would put a directory with newline (or wildcards) in their $PATH
or name a command with newline in its name. It's also hard to imagine a scenario where someone could exploit a script that makes the assumption that $PATH
won't contain newline characters.
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%2f491706%2fcould-path-contain-newlines%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
Yes, PATH
can contain newlines (even on ancient Unix system).
As to splitting any string in shell, the only way you can do it portably is with IFS
. You can use IFS=:; set -f -- $PATH
or pass it to a function instead of looping with for
, though.
With bash
you can "read" a string into an array (mapfile -td: <<< "$PATH" path
). But using arrays is usually not a good idea, because they can't be stored transparently in environment variables or passed as a single argument to external commands.
Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
– ilkkachu
1 hour ago
No, you need theset -f
to take effect before the$PATH
expansion. So it should beset -o noglob; set -- $PATH""
– Stéphane Chazelas
51 mins ago
Thatmapfile -td: <<< "$PATH"
adds a trailing newline to the last element (and needs bash 4.4 or above).
– Stéphane Chazelas
51 mins ago
add a comment |
Yes, PATH
can contain newlines (even on ancient Unix system).
As to splitting any string in shell, the only way you can do it portably is with IFS
. You can use IFS=:; set -f -- $PATH
or pass it to a function instead of looping with for
, though.
With bash
you can "read" a string into an array (mapfile -td: <<< "$PATH" path
). But using arrays is usually not a good idea, because they can't be stored transparently in environment variables or passed as a single argument to external commands.
Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
– ilkkachu
1 hour ago
No, you need theset -f
to take effect before the$PATH
expansion. So it should beset -o noglob; set -- $PATH""
– Stéphane Chazelas
51 mins ago
Thatmapfile -td: <<< "$PATH"
adds a trailing newline to the last element (and needs bash 4.4 or above).
– Stéphane Chazelas
51 mins ago
add a comment |
Yes, PATH
can contain newlines (even on ancient Unix system).
As to splitting any string in shell, the only way you can do it portably is with IFS
. You can use IFS=:; set -f -- $PATH
or pass it to a function instead of looping with for
, though.
With bash
you can "read" a string into an array (mapfile -td: <<< "$PATH" path
). But using arrays is usually not a good idea, because they can't be stored transparently in environment variables or passed as a single argument to external commands.
Yes, PATH
can contain newlines (even on ancient Unix system).
As to splitting any string in shell, the only way you can do it portably is with IFS
. You can use IFS=:; set -f -- $PATH
or pass it to a function instead of looping with for
, though.
With bash
you can "read" a string into an array (mapfile -td: <<< "$PATH" path
). But using arrays is usually not a good idea, because they can't be stored transparently in environment variables or passed as a single argument to external commands.
edited 1 hour ago
ilkkachu
55.9k784155
55.9k784155
answered 2 hours ago
pizdelect
35916
35916
Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
– ilkkachu
1 hour ago
No, you need theset -f
to take effect before the$PATH
expansion. So it should beset -o noglob; set -- $PATH""
– Stéphane Chazelas
51 mins ago
Thatmapfile -td: <<< "$PATH"
adds a trailing newline to the last element (and needs bash 4.4 or above).
– Stéphane Chazelas
51 mins ago
add a comment |
Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
– ilkkachu
1 hour ago
No, you need theset -f
to take effect before the$PATH
expansion. So it should beset -o noglob; set -- $PATH""
– Stéphane Chazelas
51 mins ago
Thatmapfile -td: <<< "$PATH"
adds a trailing newline to the last element (and needs bash 4.4 or above).
– Stéphane Chazelas
51 mins ago
Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
– ilkkachu
1 hour ago
Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
– ilkkachu
1 hour ago
No, you need the
set -f
to take effect before the $PATH
expansion. So it should be set -o noglob; set -- $PATH""
– Stéphane Chazelas
51 mins ago
No, you need the
set -f
to take effect before the $PATH
expansion. So it should be set -o noglob; set -- $PATH""
– Stéphane Chazelas
51 mins ago
That
mapfile -td: <<< "$PATH"
adds a trailing newline to the last element (and needs bash 4.4 or above).– Stéphane Chazelas
51 mins ago
That
mapfile -td: <<< "$PATH"
adds a trailing newline to the last element (and needs bash 4.4 or above).– Stéphane Chazelas
51 mins ago
add a comment |
In POSIX shells, $IFS
is a field delimiter, not separator, so a $PATH
value like /bin:/usr/bin:
would be split into /bin
and /usr/bin
instead of /bin
, /usr/bin
and the empty string (meaning the current directory). You need:
IFS=:; set -o noglob
for var in $PATH""; do
printf '<%s>n' "$var"
done
To avoid modifying global settings, you can use a shell with explicit splitting operators like zsh
:
for var in "${(s/:/@)PATH}"; do
printf '<%s>n' "$var"
done
Though in that case, zsh
already has the $path
array tied to $PATH
like in csh
/tcsh
, so:
for var in "$path[@]"; do
printf '<%s>n' "$var"
done
In any case, yes, in theory $PATH
like any variable could contain newline characters, the newline character is not special in any way when it comes to file path resolution. I don't expect anyone sensible would put a directory with newline (or wildcards) in their $PATH
or name a command with newline in its name. It's also hard to imagine a scenario where someone could exploit a script that makes the assumption that $PATH
won't contain newline characters.
add a comment |
In POSIX shells, $IFS
is a field delimiter, not separator, so a $PATH
value like /bin:/usr/bin:
would be split into /bin
and /usr/bin
instead of /bin
, /usr/bin
and the empty string (meaning the current directory). You need:
IFS=:; set -o noglob
for var in $PATH""; do
printf '<%s>n' "$var"
done
To avoid modifying global settings, you can use a shell with explicit splitting operators like zsh
:
for var in "${(s/:/@)PATH}"; do
printf '<%s>n' "$var"
done
Though in that case, zsh
already has the $path
array tied to $PATH
like in csh
/tcsh
, so:
for var in "$path[@]"; do
printf '<%s>n' "$var"
done
In any case, yes, in theory $PATH
like any variable could contain newline characters, the newline character is not special in any way when it comes to file path resolution. I don't expect anyone sensible would put a directory with newline (or wildcards) in their $PATH
or name a command with newline in its name. It's also hard to imagine a scenario where someone could exploit a script that makes the assumption that $PATH
won't contain newline characters.
add a comment |
In POSIX shells, $IFS
is a field delimiter, not separator, so a $PATH
value like /bin:/usr/bin:
would be split into /bin
and /usr/bin
instead of /bin
, /usr/bin
and the empty string (meaning the current directory). You need:
IFS=:; set -o noglob
for var in $PATH""; do
printf '<%s>n' "$var"
done
To avoid modifying global settings, you can use a shell with explicit splitting operators like zsh
:
for var in "${(s/:/@)PATH}"; do
printf '<%s>n' "$var"
done
Though in that case, zsh
already has the $path
array tied to $PATH
like in csh
/tcsh
, so:
for var in "$path[@]"; do
printf '<%s>n' "$var"
done
In any case, yes, in theory $PATH
like any variable could contain newline characters, the newline character is not special in any way when it comes to file path resolution. I don't expect anyone sensible would put a directory with newline (or wildcards) in their $PATH
or name a command with newline in its name. It's also hard to imagine a scenario where someone could exploit a script that makes the assumption that $PATH
won't contain newline characters.
In POSIX shells, $IFS
is a field delimiter, not separator, so a $PATH
value like /bin:/usr/bin:
would be split into /bin
and /usr/bin
instead of /bin
, /usr/bin
and the empty string (meaning the current directory). You need:
IFS=:; set -o noglob
for var in $PATH""; do
printf '<%s>n' "$var"
done
To avoid modifying global settings, you can use a shell with explicit splitting operators like zsh
:
for var in "${(s/:/@)PATH}"; do
printf '<%s>n' "$var"
done
Though in that case, zsh
already has the $path
array tied to $PATH
like in csh
/tcsh
, so:
for var in "$path[@]"; do
printf '<%s>n' "$var"
done
In any case, yes, in theory $PATH
like any variable could contain newline characters, the newline character is not special in any way when it comes to file path resolution. I don't expect anyone sensible would put a directory with newline (or wildcards) in their $PATH
or name a command with newline in its name. It's also hard to imagine a scenario where someone could exploit a script that makes the assumption that $PATH
won't contain newline characters.
edited 15 mins ago
answered 46 mins ago
Stéphane Chazelas
299k54564913
299k54564913
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f491706%2fcould-path-contain-newlines%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
Note that in the Bourne shell (contrary to POSIX shells),
/bin::/usr/bin
would be split into/bin
and/usr/bin
instead of/bin
,""
and/usr/bin
.– Stéphane Chazelas
20 mins ago