bat 如何传参数给 shell

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bat 如何传参数给 shell相关的知识,希望对你有一定的参考价值。

我这边windows环境下有个小工具,内含psftp和putty,可以完成拷贝tar包到linux环境下执行包,然后将执行的结果拷回windows环境下。但是现在执行包需要输入参数,不清楚如何在环境间传递参数。请各位高手给出回答,有思路也行,能贴代码更好了。

#include <stdio.h>
#include <stdlib.h>
main()

system("123.bat haha");


.bat里:
echo %1

执行后输出
haha

所以在system要执行的脚本名后面直接加上参数就可以了
#!/bin/sh

if [ $# -ne 1 ]; then
echo 1>&2 Usage: $0 [config_file]
exit 127
fi

SOURCE=`awk -F"=" '/^database_name/ print $2 ' $1`
SECONDS=`date +%s`
TARGET=$SOURCE"_"$SECONDS
DESTINATION=../$SOURCE.$DIALOG.$VERSION

echo Database: $SOURCE
echo Dialog ID: $DIALOG

#drop the target databse
psql -c "drop database $TARGET"

#create database objects
psql $TARGET < postgres_create.sql

#copy base tables
psql -c "copy (select * from message) to stdout" $SOURCE | psql -c "copy message from stdin" $TARGET

$TARGET
psql -c "copy (select * from qs_publicationstatustype) to stdout" $SOURCE | psql -c "copy qs_publicationstatustype from

stdin" $TARGET

#save the dialog
psql -c "copy (select * from q_dialog where q_dialog_id = $DIALOG) to stdout" $SOURCE | psql -c "copy q_dialog from stdin"

$TARGET

#create database objects
psql $TARGET < postgres_index.sql

#make the destination directory
mkdir -p $DESTINATION
mkdir -p $DESTINATION/cdd
mkdir -p $DESTINATION/corticon

#create readme files
echo "Note: Rules assets are owned by a different user and will have to be copied separately" >> $DESTINATION/cdd/README
echo "Note: Rules assets are owned by a different user and will have to be copied separately" >>

$DESTINATION/corticon/README

#export the database
pg_dump $TARGET > $DESTINATION/postgres_create.sql

#copy the import template to the destination
cp $TEMPLATE $DESTINATION/dialogsImport.sh
chmod +x $DESTINATION/dialogsImport.sh

#drop the temp database
psql -c "drop database $TARGET"

#append to the import config file
echo "database_name=$SOURCE" >> $DESTINATION/import.cfg

#append to the import README file

echo "*********************************************" >> $DESTINATION/README
echo "*" >> $DESTINATION/README
echo "* Program: dialogsImport" >> $DESTINATION/README
echo "*" >> $DESTINATION/README
echo "* Version 0.5" >> $DESTINATION/README
echo "*" >> $DESTINATION/README
echo "* Author: Dan Dreon" >> $DESTINATION/README
echo "*" >> $DESTINATION/README
echo "*********************************************" >> $DESTINATION/README

echo "* run this script as the database user - typically postgres" >> $DESTINATION/README
echo "* run this script from inside the dialogsImport folder" >> $DESTINATION/README
echo "* psql must be in your path" >> $DESTINATION/README
echo "* first edit the import.cfg script and enter the appropriate values" >> $DESTINATION/README
echo "* to run this script type ./dialogsImport import.cfg" >> $DESTINATION/README
echo "* Note: rules assets need to be copied separately" >> $DESTINATION/README

#archive the directory
tar -zcvf $DESTINATION.tar.gz $DESTINATION

#delete the original
rm -rf $DESTINATION

如何把这个shell脚本移植到windows 的bat中?各位大虾们,小弟现在有个棘手的问题,请大虾们给以帮助。
参考技术A 是的,直接在命令提示符下键入你的bat命令,用空格分隔参数,然后在bat中用%1就是第一个参数的内容,%2就是第二个参数的内容。追问

不是问怎么调用参数执行bat,而是如何用将bat的参数传递到shell中啊。

如何通过 docker run 将参数传递给 Shell 脚本

【中文标题】如何通过 docker run 将参数传递给 Shell 脚本【英文标题】:How to pass arguments to Shell Script through docker run 【发布时间】:2015-12-20 01:32:17 【问题描述】:

我是码头工人世界的新手。我必须调用一个通过 docker 容器获取命令行参数的 shell 脚本。 例如:我的 shell 脚本如下所示:

#!bin/bash
echo $1

Dockerfile 看起来像这样:

FROM ubuntu:14.04
COPY ./file.sh /
CMD /bin/bash file.sh

我不确定如何在运行容器时传递参数

【问题讨论】:

【参考方案1】:

使用相同的file.sh

#!/bin/bash
echo $1

使用现有的 Dockerfile 构建镜像:

docker build -t test .

使用参数 abcxyz 或其他参数运行图像。

docker run -ti --rm test /file.sh abc

docker run -ti --rm test /file.sh xyz

【讨论】:

如果您不希望最终用户直接了解 file.sh,我认为 ENTRYPOINT 是您的最佳选择。 你怎么能像docker run -ti test /file.sh abc这样开始一个脚本。我觉得脚本不会运行,因为它应该是docker run -ti test sh /file.sh abc。 sh 或 /bin/sh 将正确运行它。 对于其他来这里的人。 /usr/bin/env 技巧是可选的样式偏好,不是让它工作的必要条件。还有#!行指示使用哪个解释器购买默认值。所以它可以通过调用脚本来运行。【参考方案2】:

file.sh 中使用此脚本

#!/bin/bash
echo Your container args are: "$@"

还有这个Dockerfile

FROM ubuntu:14.04
COPY ./file.sh /
ENTRYPOINT ["/file.sh"]

你应该能够:

% docker build -t test .
% docker run test hello world
Your container args are: hello world

【讨论】:

如果你像我一样忘记了 "/file.sh" 周围的 "",它就不起作用了。 由于某种原因,这不适用于ENTRYPOINT ./file.sh 别忘了chmod +x file.sh 设置可执行标志。 @kev ,你知道为什么会这样吗? ["/file.sh"]/file.sh 甚至 [/file.sh] 有什么区别 @Nitzankin 查看我的回答,了解为什么需要正确的 json 格式。【参考方案3】:

另一种选择...

为了实现这一目标

docker run -d --rm $IMG_NAME "bash:command1&&command2&&command3"

在 dockerfile 中

ENTRYPOINT ["/entrypoint.sh"]

在 entrypoint.sh 中

#!/bin/sh

entrypoint_params=$1
printf "==>[entrypoint.sh] %s\n" "entry_point_param is $entrypoint_params"

PARAM1=$(echo $entrypoint_params | cut -d':' -f1) # output is 1 must be 'bash' it     will be tested    
PARAM2=$(echo $entrypoint_params | cut -d':' -f2) # the real command separated by     &&

printf "==>[entrypoint.sh] %s\n" "PARAM1=$PARAM1"
printf "==>[entrypoint.sh] %s\n" "PARAM2=$PARAM2"

if [ "$PARAM1" = "bash" ];
then
    printf "==>[entrypoint.sh] %s\n" "about to running $PARAM2 command"
    echo $PARAM2 | tr '&&' '\n' | while read cmd; do
        $cmd
    done    
fi

【讨论】:

一些注意事项和限制......带有“:”的命令需要在 cut -d':' 中进行更改,并且像 docker run -d --rm $IMG_NAME "bash:echo $PATH" 这样的命令将显示主机路径值而不是主机路径值【参考方案4】:

这里有一些交互的东西:

    docker run your_image arg1 arg2 会将CMD 的值替换为arg1 arg2。这是对 CMD 的完全替代,而不是向其附加更多值。这就是为什么您经常看到docker run some_image /bin/bash 在容器中运行 bash shell。

    当您同时定义了 ENTRYPOINT 和 CMD 值时,docker 通过连接两者并运行该连接命令来启动容器。因此,如果您将入口点定义为file.sh,您现在可以使用附加参数运行容器,这些参数将作为参数传递给file.sh

    docker 中的入口点和命令有两种语法,一种是启动 shell 的字符串语法,一种是执行 exec 的 json 语法。 shell 可用于处理诸如 IO 重定向、将多个命令链接在一起(使用 &amp;&amp; 之类的东西)、变量替换等事情。但是,该 shell 妨碍了信号处理(如果你曾经见过 10 秒延迟停止容器,这通常是原因)并将入口点和命令连接在一起。如果您将入口点定义为字符串,它将运行/bin/sh -c "file.sh",仅此一项就可以了。但是如果你也有一个定义为字符串的命令,你会看到像/bin/sh -c "file.sh" /bin/sh -c "arg1 arg2" 这样的命令在你的容器中启动,不是很好。见the table here for more on how these two options interact

    shell -c 选项只接受一个参数。之后的所有内容都将作为 $1$2 等传递给该单个参数,但不会传递给嵌入式 shell 脚本,除非您明确传递参数。 IE。 /bin/sh -c "file.sh $1 $2" "arg1" "arg2" 会起作用,但 /bin/sh -c "file.sh" "arg1" "arg2" 不会,因为 file.sh 会在没有参数的情况下被调用。

综上所述,共同的设计是:

FROM ubuntu:14.04
COPY ./file.sh /
RUN chmod 755 /file.sh
# Note the json syntax on this next line is strict, double quotes, and any syntax
# error will result in a shell being used to run the line.
ENTRYPOINT ["file.sh"]

然后你运行它:

docker run your_image arg1 arg2

这里有更多详细信息:

https://docs.docker.com/engine/reference/run/#cmd-default-command-or-options https://docs.docker.com/engine/reference/builder/#exec-form-entrypoint-example

【讨论】:

我曾尝试将入口点设置为 ["bash", "--login", "-c"] 以获取映像中的 /etc/profile 源,但后来我想知道为什么没有 args 会传递给传递给 docker run 的 shell 脚本...您的回答澄清了这一点,谢谢! 作为一个刚接触 Docker 的人,我觉得这个解释是最好的 - 非常清楚,有很多背景信息解释了为什么事情会以它们的方式工作或不工作。【参考方案5】:

我拥有的是一个实际运行的脚本文件。这个脚本文件可能相对复杂。我们称之为“run_container”。此脚本从命令行获取参数:

run_container p1 p2 p3

一个简单的 run_container 可能是:

#!/bin/bash
echo "argc = $#*"
echo "argv = $*"

我想做的是,在“dockering”之后,我希望能够使用 docker 命令行上的参数启动这个容器,如下所示:

docker run image_name p1 p2 p3

并以 p1 p2 p3 作为参数运行 run_container 脚本。

这是我的解决方案:

Dockerfile:

FROM docker.io/ubuntu
ADD run_container /
ENTRYPOINT ["/bin/bash", "-c", "/run_container \"$@\"", "--"]

【讨论】:

ENTRYPOINT数组中的第三个值替换为"/run_container \"$@\""意味着包含空格的参数被正确处理(例如docker run image_name foo 'bar baz' quux)。 在我的 bash 文件中添加 switch/case 语句后,ENTRYPOINT["run_container.sh"] 不再对我有用,但是 ENTRYPOINT["sh", "-c", "run_container.sh" ] 将不再接受我的参数。这个解决方案(有@davidchambers 的建议)对我有用。【参考方案6】:

如果你想在@build time 运行它:

CMD /bin/bash /file.sh arg1

如果你想运行它@run time:

ENTRYPOINT ["/bin/bash"]
CMD ["/file.sh", "arg1"]

然后在主机shell中

docker build -t test .
docker run -i -t test

【讨论】:

ENTRYPOINT 对于我认为想要运行时的 OP 来说是一个很好的答案,但如果你真的想要构建时间变量,这个答案就被打破了。使用ARGdocker build --build-arg docs.docker.com/engine/reference/builder/#arg【参考方案7】:

使用 Docker,传递此类信息的正确方法是通过环境变量。

所以用同样的Dockerfile,把脚本改成

#!/bin/bash
echo $FOO

构建完成后,使用以下 docker 命令:

docker run -e FOO="hello world!" test

【讨论】:

为什么这是投票最高的答案?环境变量是传递信息的另一种方式,但这不是 OP 所要求的。当然,OP 将 args 传递给容器的愿望绝对没有任何不当之处。 在 SO 上有很多 XY 问题。由于 OP 声明他们是 Docker 的新手,因此完全合理的答案显示了实现目标的推荐方式。因此,这是一个很好的答案。 完成工作的最简单方法,而不是将变量作为构建参数传递和所有这些混乱。对于将机密作为环境变量传递非常有用。 我遇到了一个棘手的情况,我需要一个带有空格的参数来传递给入口点内的命令。 pytest -m "not longest" 这是唯一对我有用的解决方案。 “合适”与否,我很高兴它在这里。

以上是关于bat 如何传参数给 shell的主要内容,如果未能解决你的问题,请参考以下文章

将带有空格的路径作为参数传递给 bat 文件

往shell脚本中传入参数

如何通过asp.net schtasks将参数传递给bat文件

VB调用SHELL,参数路径有空格如何处理?

winform 如何传参数给网页 并且把值赋值给该页面的元素

shell脚本传参中包含有空格的参数