是否可以简化此 BASH eval 表达式?
Is it possible to simplify this BASH eval expression?
给定以下 Bash shell 脚本摘录:
# The intent is to take the PATH env variable, break it up into its parts, making them
# appear to be command line args (i.e., ``, ``, ...), and then for this example, just
# echo the parts in space delimited form, but we can imagine that we may want to do other
# things with them - this is just sample usage
# Important Requirement/Constraint
# ================================
# Please do not alter the "PATH to , , , ..." portion of the answer or replace the
# Bash ".." range construct with the output of the "seq" command exec'd in a subshell.
# Preferably, the answer should simply consist of the simplification of the last line of
# code - the "eval eval ..." . Also, please don't simplify by collapsing the whole thing
# to just echo "$@" since we may want to work with only some of the parts, and not
# necessarily the first parts, of the path. That is to say that the 1 and $# in the
# {1..$#} range could be replaced with other shell variables or expr., potentially
# Test case
PATH=/usr/local/bin:/usr/bin:/bin
# The code being examined follows
# Set ':' as the input field separator of the path
IFS=: # Or, more appropriately if in a function: local IFS=:
# Parse the PATH environment variable and break it up into its components
set $PATH
# This is the line we want to simplify, if possible, without losing functionality of
# course (see the comment that follows for details)
eval eval echo '\'$(eval 'echo "${1..$#}"')
# Some notes and explanations regarding the functionality and underlying intent of the
# preceding line:
# - We start by dynamically creating the following construct: ${1..3}
# since $# is 3 for our example
# - Use Bash to expand that construct to:
# these vars contain the parsed parts of the PATH
# - Finally, display the three parts of the PATH using echo: echo
# - This causes the following text to be sent to STDOUT:
# /usr/local/bin /usr/bin /bin
那么,是否可以简化前面代码中的 eval eval...
行,但仍然产生所需的输出,对于上面的示例是:
/usr/local/bin /usr/bin /bin
我正在考虑一个解决方案,该解决方案将用 input/output 重定向(可能)或可能导致 reordering/collapsing 的各种命令替换某些 echo
命令需要的 eval
个命令少于示例中使用的命令。
echo "${PATH}" | tr ':' '\n' > stack
count=1
echo "#/bin/sh-" | tr '-' '\n' >> stack2
while read line
do
echo "path${count}=${line}" >> stack2
count=$(($count+1))
done < stack
source stack2
现在您已经在其自己的命名变量中获得了路径的每个部分。
贴近原文,你可以做到
IFS=:
set $PATH
echo "$@"
如果你不想改变IFS
和PATH
,你可以
set $(sed 's/[^=]*=//;s/:/ /g' <<< ${PATH})
echo "$@"
but still produce the desired output,
/usr/local/bin /usr/bin /bin
刚刚:
echo "${PATH//:/ }"
The intent is to take the PATH env variable, break it up into its parts, making them
appear to be command line args (i.e., </code>, <code>
, ...), and then for this example, just
echo the parts in space delimited form, but we can imagine that we may want to do other
things with them - this is just sample usage
我不相信未引用的 shell 扩展。
IFS=':' read -ra patharr <<<"$PATH"
set -- "${patharr[@]}"
IFS=' '; printf "%s\n" "${patharr[*]}"
给定以下 Bash shell 脚本摘录:
# The intent is to take the PATH env variable, break it up into its parts, making them
# appear to be command line args (i.e., ``, ``, ...), and then for this example, just
# echo the parts in space delimited form, but we can imagine that we may want to do other
# things with them - this is just sample usage
# Important Requirement/Constraint
# ================================
# Please do not alter the "PATH to , , , ..." portion of the answer or replace the
# Bash ".." range construct with the output of the "seq" command exec'd in a subshell.
# Preferably, the answer should simply consist of the simplification of the last line of
# code - the "eval eval ..." . Also, please don't simplify by collapsing the whole thing
# to just echo "$@" since we may want to work with only some of the parts, and not
# necessarily the first parts, of the path. That is to say that the 1 and $# in the
# {1..$#} range could be replaced with other shell variables or expr., potentially
# Test case
PATH=/usr/local/bin:/usr/bin:/bin
# The code being examined follows
# Set ':' as the input field separator of the path
IFS=: # Or, more appropriately if in a function: local IFS=:
# Parse the PATH environment variable and break it up into its components
set $PATH
# This is the line we want to simplify, if possible, without losing functionality of
# course (see the comment that follows for details)
eval eval echo '\'$(eval 'echo "${1..$#}"')
# Some notes and explanations regarding the functionality and underlying intent of the
# preceding line:
# - We start by dynamically creating the following construct: ${1..3}
# since $# is 3 for our example
# - Use Bash to expand that construct to:
# these vars contain the parsed parts of the PATH
# - Finally, display the three parts of the PATH using echo: echo
# - This causes the following text to be sent to STDOUT:
# /usr/local/bin /usr/bin /bin
那么,是否可以简化前面代码中的 eval eval...
行,但仍然产生所需的输出,对于上面的示例是:
/usr/local/bin /usr/bin /bin
我正在考虑一个解决方案,该解决方案将用 input/output 重定向(可能)或可能导致 reordering/collapsing 的各种命令替换某些 echo
命令需要的 eval
个命令少于示例中使用的命令。
echo "${PATH}" | tr ':' '\n' > stack
count=1
echo "#/bin/sh-" | tr '-' '\n' >> stack2
while read line
do
echo "path${count}=${line}" >> stack2
count=$(($count+1))
done < stack
source stack2
现在您已经在其自己的命名变量中获得了路径的每个部分。
贴近原文,你可以做到
IFS=:
set $PATH
echo "$@"
如果你不想改变IFS
和PATH
,你可以
set $(sed 's/[^=]*=//;s/:/ /g' <<< ${PATH})
echo "$@"
but still produce the desired output,
/usr/local/bin /usr/bin /bin
刚刚:
echo "${PATH//:/ }"
The intent is to take the PATH env variable, break it up into its parts, making them appear to be command line args (i.e.,
</code>, <code>
, ...), and then for this example, just echo the parts in space delimited form, but we can imagine that we may want to do other things with them - this is just sample usage
我不相信未引用的 shell 扩展。
IFS=':' read -ra patharr <<<"$PATH"
set -- "${patharr[@]}"
IFS=' '; printf "%s\n" "${patharr[*]}"