在bash

时间:2015-05-11 13:59:59

标签: linux bash shell talend

我有几十个脚本,都在不同的目录中。 (导出/扩展的Talend工作)

此时每个作业都有1个或2个脚本,从相同的行开始,最重要的一个:

CD ***path-to-script***

和几行来设置Java路径并启动作业。

我想创建一个脚本,该脚本将从所有这些脚本中运行。 e.g:

/scripts/talend.sh

在所有talend脚本中,第一行将运行/scripts/talend.sh,这些脚本的运行位置示例如下:

/talend-job1_0.1/talend-job1_0.1/talend-job1/talend-job1.sh
/talend-task2_0.1/talend-task2_0.1/talend-task2/talend-task2.sh
/talend-job3_0.1/talend-job3_0.1/talend-job3/talend-job3.sh

如何确定/scripts/talend.sh的起始位置,以便我可以从/scripts/talend.sh内CD到该路径。

Talend脚本不是从目录本身运行,而是从cronjob或不同的用户主目录运行。

编辑: 该问题被标记为重复,但Getting the source directory of a Bash script from within并未100%回答我的问题。 问题是:   - 从不同的脚本调用基本脚本   - 这些不同的脚本可以从命令行运行,带有或不带符号链接。   - $ 0,$ BASH_SOURCE和pwd都做了一些事情,但没有提到的解决方案涵盖了所有的困难。

示例:

/scripts/talend.sh   

在这个脚本中,我想配置Java的$ PATH和$ HOME_PATH,以及配置Talend作业的地方的CD。 (这是一个包,所以必须从该位置运行脚本)。

工作路径例如是:

/u/talend/talendjob1/sub../../talendjob1.sh 
/u/talend/talendjob2/sub../../talendjob2.sh
/u/talend/talendjob3/sub../../talendjob3.sh

从TMS应用程序运行多个作业。此应用程序无法使用whol名称运行这些脚本(对于long,名称只能是6长),因此在不同的位置我有符号链接:

/u/tms/links/p00001 -> /u/talend/talendjob1/sub../../talendjob1.sh
/u/tms/links/p00002 -> /u/talend/talendjob1/sub../../talendjob2.sh
/u/tms/links/p00003 -> /u/talend/talendjob1/sub../../talendjob3.sh
/u/tms/links/p00004 -> /u/talend/talendjob1/sub../../talendjob4.sh

我认为你会对复杂性有所了解,为什么我只想要一个基本的talend脚本,我可以留下所有基本内容。但是我只能这样做,如果我知道Talend脚本的来源,因为我必须要开始这个talend工作。

5 个答案:

答案 0 :(得分:5)

这些答案(超出第一个答案)特定于Linux,但应该非常强大 - 使用包含空格,文字换行符,通配符等的目录名称。

要更改为您自己的源目录(其他地方的常见问题解答):

cd "$(basename "$BASH_SOURCE")"

要更改为父进程的当前目录:

cd "/proc/$PPID/cwd"

如果要更改为作为父进程的第一个命令行参数传递的目录:

{ IFS= read -r -d '' _ && IFS= read -r -d '' argv1; } <"/proc/$PPID/cmdline"
cd "$argv1"

那就是说,我个人只是将作业目录导出到父进程中的环境变量,并在子进程中读取该环境变量。更简单,更简单,更便携,更准确,并符合最佳流程。

答案 1 :(得分:1)

您可以将pwd存储在变量中,然后在您想要返回时cd存储

答案 2 :(得分:1)

当您使用/scripts/talend.sh时,当前目录不变:

脚本

# cat /scripts/talend.sh
echo "Talend: $(pwd)"
# cat /talend-job1_0.1/talend-job1_0.1/talend-job1/talend-job1.sh
echo Job1
. /scripts/talend.sh

执行job1

# cd /talend-job1_0.1/talend-job1_0.1
# talend-job1/talend-job1.sh
Job1
Talend: /talend-job1_0.1/talend-job1_0.1

如果要查看调用脚本所在的目录,请参阅get dir of script

编辑: 如果你想拥有callling脚本的路径(talend-job1.sh)而不必先cd到那个dir,你应该得到脚本的dir(见上面的链接)和source talend.sh:

# cat /scripts/talend.sh
cd "$( dirname "${BASH_SOURCE[0]}" )"
echo "Talend: $(pwd)"

答案 3 :(得分:1)

talend.sh中获取调用脚本的名称,然后获取目录:

parent_cmd=$(ps -o args= $PPID)
set -- $parent_cmd
parent_cmd=$(dirname $2)

更新:正如Charles Duffy在下面的评论中所指出的那样,当与包含空白或glob模式的路径一起使用时会造成严重破坏。

如果procfs可用,您可以阅读/proc/$PPID/cmdline的内容,或者如果可移植性是一个问题,请更好地解析args

答案 4 :(得分:1)

/scripts/talend.sh

cd "$(dirname "$0")"

或者:

cd "$(dirname "$BASH_SOURCE")"

另一个是:

cd "$(dirname "$_")"
#This must be the first line of your script after the shebang line
#Otherwise don't use it

注意:以上最可靠的是$BASH_SOURCE