shell中的动态变量

shell中的动态变量

我有一个以下脚本,它将从用户那里获取输入(源路径),并将附加到 docker 容器内的卷

echo -n "Enter the source path: "

read path

docker run -v $path:/opt/$path/ fedora

问题是,我想创建一个循环,以便用户可以提供多个源路径并且可以将其附加到docker容器。

例如

docker run -v $path1:/opt/$path1 -v $path2:/opt/$path2

等等,这些$path变量的数量取决于用户输入。

答案1

在 中bash,您应该使用数组来保存从用户读取的路径。一般来说,最好将单独的字符串(路径名)分开,而不是将它们连接成一个字符串,稍后您必须正确解析该字符串以提取原始的组成字符串。

#!/bin/bash

echo 'Enter paths, one by one followed by Enter. End input with Ctrl+D' >&2
mypaths=()
while IFS= read -r -p 'Path: ' thepath; do
   mypaths+=( -v "$thepath:/opt/$thepath" )
done

docker run "${mypaths[@]}" fedora

这里,用户需要多次输入路径,直到按下Ctrl+D。输入的路径保存在mypaths数组中,数组的布局方式docker可以直接使用。

一旦没有更多路径可供读取,docker就会调用该命令。将"${mypaths[@]}"扩展到数组中单独引用的元素mypaths。由于数组的条目按原样存储(-v在每个特殊格式的字符串之前作为单独的元素pathname:/opt/pathname),因此 shell 和docker.上述代码在路径名中唯一不能容忍的字符是换行符,因为它们分隔了 读取的行read

上面的脚本还接受从每行输入包含单个路径的文本文件重定向的输入。

请注意,引用很重要。如果变量扩展周围没有双引号,您将无法使用包含空格的路径,并且包含 shell 特殊字符的路径也可能会出现问题。

有关的:


对于非bash( sh) 外壳:

#!/bin/sh

echo 'Enter paths, one by one followed by Enter. End input with Ctrl+D' >&2
set --
while printf 'Path: ' >&2 && IFS= read -r thepath; do
   set -- "$@" -v "$thepath:/opt/$thepath"
done

docker run "$@" fedora

在这里,我们使用位置参数列表而不是数组(因为除此之外的数组通常$@不可用sh),但除了使用 显式打印提示之外,工作流程在其他方面是相同的printf


实施Stéphane Chazelas 评论末尾的建议,以便脚本在其命令行上获取路径名,而不是从标准输入中读取它们。这允许用户将任意路径名传递给脚本,即使是那些read无法轻松读取或用户无法轻松在键盘上键入的路径名。

对于bash使用数组:

#!/bin/bash

for pathname do
    mypaths+=( -v "$pathname:/opt/$pathname" )
done

docker run "${mypaths[@]}" fedora

对于sh使用位置参数列表:

#!/bin/sh

for pathname do
    shift
    set -- "$@" -v "$pathname:/opt/$pathname"
done

docker run "$@" fedora

这两个都会像这样运行

./script.sh path1 path2 path3 ...

答案2

试试这个,目录名称不能包含空格:

#!/bin/bash

echo -n "Enter the Directories, space separated : "
read dirs

docker run $( set -- $dirs; for path; do echo -v $path:/opt/$path/; done ) fedora

输入类似的内容foo bar,它将运行

docker run -v foo:/opt/foo/ -v bar:/opt/bar/ fedora

答案3

#!/bin/bash

echo -n "Enter the Path : "
read path
echo -n "docker run "
echo "${path}" | tr " " "\n" | while read value
do
    echo -n "-v ${value}:/opt/${value} "
done

相关内容