我正在寻找一个简单的解决方案来检索当前脚本的绝对路径。它需要独立于平台(我希望它可以在 linux、freebsd、macos 和没有 bash 的情况下工作)。
编辑:检索脚本存储库路径的解决方案:
DIR="$( cd "$( dirname "$0" )" && pwd )"(来源:从内部获取 Bash 脚本的源目录)
根据 POSIX:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html
在某些情况下,它并不明显。例如:
If the file is not in the current working directory,
the implementation may perform a search for an executable
file using the value of PATH, as described in Command Search and Execution.
Run Code Online (Sandbox Code Playgroud)
我的 Bash 4.x 没有遵循这个可选规则(出于安全考虑??)所以我无法测试它在现实生活中的情况......
在shell脚本中查找shell可执行文件目录的平台独立方式是什么?
附注。此外dirname $0案例失败:
#!/bin/sh
echo $0
dirname $0
Run Code Online (Sandbox Code Playgroud)
当你:
$ sh runme.sh
runme.sh
.
Run Code Online (Sandbox Code Playgroud)
所以你需要这样的东西:
CMDPATH=`cd $(dirname $0); echo $PWD`
Run Code Online (Sandbox Code Playgroud)
为了使代码仅依赖于内置 shell 功能,我将代码重写为:
PREVPWD=$PWD
cd ${0%${0##*/}}.
CMDPATH=$PWD
cd $PREVPWD
Run Code Online (Sandbox Code Playgroud)
这看起来很丑,但不需要 fork 任何可执行文件......
我有一个java应用程序。我使用 Runtime.getRuntime().exec 来调用批处理文件。当我使用 Runtime.getRuntime().exec 调用 Linux 批处理文件时,批处理文件找不到自己的目录。我在批处理文件中使用 pwd 命令,但它返回应用程序路径。我需要批处理文件本身的物理路径。我怎样才能做到这一点?
我为我的项目设置了gitlab-ci,并插入了以下yml脚本:
---
buildJob:
only:
- master
script:
- "sh /var/www/gitTestFolder/scripts/build.sh"
stage: build
tags:
- ipsenh
deployJob:
only:
- master
script:
- "sh /var/www/gitTestFolder/scripts/deploy.sh"
stage: deploy
tags:
- ipsenh
testJob:
only:
- master
script:
- "sh /var/www/gitTestFolder/scripts/test.sh"
stage: test
tags:
- ipsenh
stages:
- build
- test
- deploy
Run Code Online (Sandbox Code Playgroud)
该脚本在我的gitlab服务器中运行,并显示应执行脚本的终端(/var/www..../script.sh)。
以下结果是我的一项工作:
gitlab-ci-multi-runner 0.6.2 (3227f0a)
Using Shell executor...
Running on ipsenh...
Cloning repository...
Cloning into 'builds/05d0538a/0/root/ipsenh'...
Checking out 4288f64a as master...
$ sh /var/www/gitTestFolder/scripts/deploy.sh
Build succeeded.
Run Code Online (Sandbox Code Playgroud)
但是,脚本永远不会执行。如果我在服务器上本地执行此脚本,它将创建带有简单文本输出的文件。但是,它永远不会通过此作业创建文件。
脚本内容:
echo "job …
我有3个脚本:
脚本A:
echo "Hey you!"
Run Code Online (Sandbox Code Playgroud)
脚本B:
source ./A.sh
Run Code Online (Sandbox Code Playgroud)
脚本 C:
source ./libs/B.sh
Run Code Online (Sandbox Code Playgroud)
因此,文件夹“libs”中的脚本 A 和 B 以及脚本 C 使用此目录中的脚本 B。
脚本 C 抛出错误:
./libs/B.sh: line 1: ./A.sh: 没有那个文件或目录
在这种情况下如何更正使用脚本“包括”?
我明白为什么会发生这个错误,但我不明白如何解决它。还!我不想将完整路径包含为 /home /.../libs/A.sh 等。我想创建无需永久编辑的免移动脚本。
我在 bash 和子EXITshell 内发现了一些奇怪的行为。我希望以下四行都输出相同的内容(“嗨被困”):
a=$(trap 'echo trapped' EXIT ; echo hi); echo $a
a=$(trap 'echo trapped' EXIT && echo hi); echo $a
a=$(trap 'echo trapped' EXIT ; /bin/echo hi); echo $a
a=$(trap 'echo trapped' EXIT && /bin/echo hi); echo $a
Run Code Online (Sandbox Code Playgroud)
前三个确实打印了“hi trap”,但最后一个不是。它只是输出“hi”。陷阱没有被调用。您可以通过以下方式验证这一点set -x:
set -x; a=$(trap 'echo trapped' EXIT ; echo hi); set +x; echo $a
set -x; a=$(trap 'echo trapped' EXIT && echo hi); set +x; echo $a
set -x; a=$(trap 'echo trapped' EXIT ; …Run Code Online (Sandbox Code Playgroud) 有没有一种蛮力的方式来做到这一点?
#!/bin/ksh
THIS_SCRIPT=$(/usr/bin/readlink -f $(echo $0 | /bin/sed "s,^[^/],$PWD/&,"))
echo $THIS_SCRIPT
Run Code Online (Sandbox Code Playgroud)
我坚持使用,ksh但更喜欢也适用的解决方案bash(我认为这样做).
我在Bash脚本中使用它来获取我运行脚本的路径.在OS X中双击.command文件是必要的.
#!/bin/bash
BASEDIR=$(dirname $0)
cd $BASEDIR
Run Code Online (Sandbox Code Playgroud)
问题是当路径有空格时它不起作用.你怎么能解决这个问题?
作为一个实例,我.bashrc使用以下方式的相对路径,虽然我的问题是关于使用的任何临时变量源其他脚本.bashrc.
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $DIR/.somefile
现在我把DIR每一个壳弄得乱七八糟.没有明确unset DIR的结尾.bashrc,有没有办法限制变量的范围?
[ 编辑 ]要查看列表:( set -o posix ; set ) | less
假设我有以下脚本文件:
~/src/setup.sh: :
#!/usr/bin/env bash
dn=$( dirname "$0" )
source "$dn/init/init.sh"
Run Code Online (Sandbox Code Playgroud)
~/src/init/init.sh :
#!/usr/bin/env bash
dn=$( dirname "$0" )
source "$dn/start.sh"
start_servers "param1" "param2"
Run Code Online (Sandbox Code Playgroud)
~/src/init/start.sh :
#!/usr/bin/env bash
start_servers() {
# ...
printf "start the servers..."
# ...
}
Run Code Online (Sandbox Code Playgroud)
采购第二个文件 ( start.sh ) 结果:
$ ./setup.sh
./init/init.sh: line 4: ./start.sh: No such file or directory
./init/init.sh: line 6: start_servers: command not found
Run Code Online (Sandbox Code Playgroud)
由于我从执行setup.sh.,在获取文件后,start.sh似乎也来自,.但我想从其正确的位置获取它。
知道如何修复它吗?提前致谢。