草庐IT

linux shell 切换或得到shell脚本文件所在目录的完整路径(绝对路径) | $( dirname “$0“ ) 和 ${BASH_SOURCE[0]

西京刀客 2024-05-22 原文

文章目录

切换或得到shell脚本文件所在目录的完整路径(绝对路径)

$( dirname “$0“ ) 不推荐使用

demo:

SCRIPT_PATH="$( cd "$( dirname "$0" )" >/dev/null 2>&1 && pwd )"
cd "$SCRIPT_PATH/.." || exit

在linux中,dirname命令可以返回文件所在的目录。$0表示Shell本身的文件名。
因此此写法的作用为:
这个语句的作用是获取shell脚本所在目录的绝对路径,然后切换到 脚本 所在的目录。

这个脚本是有缺陷的,例如:脚本A source 了另一个⽬目录下的脚本B, 然后脚本B尝试使⽤用此法获取路路径时得到的是A的路路径

脚本中引用脚本推荐使用 ${BASH_SOURCE[0]

dirname

dirname的功能是去掉文件路径名中的从右往左数的第一个/及其之后的所有文字,查看dirname的help信息可以看到如下的例子

[root@dev workspace]# dirname --help
Usage: dirname [OPTION] NAME...
Output each NAME with its last non-slash component and trailing slashes
removed; if NAME contains no /'s, output '.' (meaning the current directory).

  -z, --zero     end each output line with NUL, not newline
      --help     display this help and exit
      --version  output version information and exit

Examples:
  dirname /usr/bin/          -> "/usr"
  dirname dir1/str dir2/str  -> "dir1" followed by "dir2"
  dirname stdio.h            -> "."

GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Full documentation at: <https://www.gnu.org/software/coreutils/dirname>
or available locally via: info '(coreutils) dirname invocation'
[root@dev workspace]#

"."表示当前路径

SCRIPT_PATH="$( cd "$( dirname "$0" )" >/dev/null 2>&1 && pwd )"

结合上面基础,此时$(dirname $0)的结果就是.,那么cd $(dirname $0)就是cd . ,之后运行pwd,此时获得的就是脚本所在的绝对路径了。

注意:dirname获取的是去掉文件路径名中的从右往左数的第一个/及其之后的所有文字。 我们在使用时,和我们调脚本的方式息息相关,我们使用绝对路径直接调脚本,还是进入第特定目录,再调脚本显示结果很大不一样。

工作中,我们有时候直接全路径调某个脚本没有问题,进入到脚本所在目录调反而出现问题,就要注意检查这里。 可能我们的脚本里面引用了dirname获取的路径,但是由于我们的调用方式不一样,获取的路径就不一样。我们别写shell脚本时,可能很多地方用到了这个路径。

$() 和 ${}

  • 在 bash shell 中, ( ) 是将括号内命令的执行结果赋值给变量。用 ()是将括号内命令的执行结果赋值给变量。 用 ()是将括号内命令的执行结果赋值给变量。用( )的理由:

    • 很容易与’ '(单引号)搞混。有时在一些奇怪的字形显示中,两种符号是一模一样的(直竖两点)。
    • 在多层次的复合替换中, 须要额外的跳脱(`)处理,而$( )则比较直观。
      $( )的不足
    • ``基本上可在全部的unix shell中使用,若写成shell script移植性比较高。而$( )并不是每一种shell都能使用。
  • 是用来作变量替换。一般情况下, {} 是用来作变量替换。一般情况下, 是用来作变量替换。一般情况下,var 与 ${var} 并没有啥不一样。但是用 ${ } 会比较精确的界定变量名称的范围
    示例如下:

[root@dev workspace]# A=B
[root@dev workspace]# echo $AB

[root@dev workspace]# echo ${A}B
BB
[root@dev workspace]#

${BASH_SOURCE[0] 推荐使用

我们可以在bash中使用以下命令获取所执行脚本文件的绝对路径

#!/bin/bash
DIR=$( cd "$(dirname "${BASH_SOURCE[0]}")" && pwd);
echo $DIR
  • BASH_SOURCE[0] - 等价于 BASH_SOURCE ,取得当前执行的 shell 文件所在的路径及文件名
  • dirname - 去除文件名中的非目录部分,仅显示与目录有关的部分
  • $() - 相当于 command, 即获取command命令的结果
  • && - 逻辑运算符号,只有当&&左边运行成功时才会运行&&右边的命令

${BASH_SOURCE[0]}表示bash脚本的第一个参数(如果第一个参数是bash,表明这是要执行bash脚本,这时"${BASH_SOURCE[0]}"自动转换为第二个参数

通过上面示例,得到shell脚本文件所在完整路径(绝对路径)及文件名(无论source,sh,.三种调用方式),且不改变shell的当前目录。

亲测,好用!

有关linux shell 切换或得到shell脚本文件所在目录的完整路径(绝对路径) | $( dirname “$0“ ) 和 ${BASH_SOURCE[0]的更多相关文章

  1. ruby-on-rails - Ruby on Rails with Haml - 如何从 erb 切换 - 2

    我正在从erb文件切换到HAML。我将hamlgem添加到我的系统中。我创建了app/views/layouts/application.html.haml文件。我应该只删除application.html.erb文件吗?此外,仍然有/public/index.html文件被呈现为默认页面。我想创建自己的默认index.html.haml页面。我应该把它放在哪里以及如何使系统呈现该文件而不是默认索引文件?谢谢! 最佳答案 是的,您可以删除任何已转换为HAML的View的ERB版本。至于你的另一个问题,删除public/index/h

  2. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  3. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

    这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

  4. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  5. ruby-on-rails - Rails - 使用/自定义 URL : '/dashboard' 指定根路径 - 2

    如何使此根路径转到:“/dashboard”而不仅仅是http://example.com?root:to=>'dashboard#index',:constraints=>lambda{|req|!req.session[:user_id].blank?} 最佳答案 您可以通过以下方式实现:root:to=>redirect('/dashboard')match'/dashboard',:to=>"dashboard#index",:constraints=>lambda{|req|!req.session[:user_id].b

  6. ruby - 如何根据长度将路径数组转换为嵌套数组或散列 - 2

    我需要根据字符串路径的长度将字符串路径数组转换为符号、哈希和数组的数组给定以下数组:array=["info","services","about/company","about/history/part1","about/history/part2"]我想生成以下输出,对不同级别进行分组,根据级别的结构混合使用符号和对象。产生以下输出:[:info,:services,about:[:company,history:[:part1,:part2]]]#altsyntax[:info,:services,{:about=>[:company,{:history=>[:part1,:pa

  7. ruby - 从 Ruby : capturing the output while displaying the output? 运行 shell 命令 - 2

    我有一个问题。我想从另一个ruby​​脚本运行一个ruby​​脚本并捕获它的输出信息,同时让它也输出到屏幕。亚军#!/usr/bin/envrubyprint"Enteryourpassword:"password=gets.chompputs"Hereisyourpassword:#{password}"我运行的脚本文件:开始.rboutput=`runner`putsoutput.match(/Hereisyour(password:.*)/).captures[0].to_s正如您在此处看到的那样,存在问题。在start.rb的第一行,屏幕是空的。我在运行程序中看不到“输入您的密

  8. ruby - 在 Ruby 的 if 语句中检查 bash 命令 - 2

    如何在Ruby的if语句中检查bash命令的返回值(true/false)。我想要这样的东西,if("/usr/bin/fswscell>/dev/null2>&1")has_afs="true"elsehas_afs="false"end它会提示以下错误含义,它总是返回true。(irb):5:warning:stringliteralincondition正确的语法是什么?更新:/usr/bin/fswscell寻找afs安装和运行状态。它会抛出这样的字符串,Thisworkstationbelongstocell如果afs没有运行,命令以状态1退出 最

  9. ruby - 可以正常中断的来自 Rake 的长时间运行的 shell 命令? - 2

    在几个项目中,我希望有一个类似rakeserver的rake任务,它将通过任何需要的方式开始为该应用程序提供服务。这是一个示例:task:serverdo%x{bundleexecrackup-p1234}end这行得通,但是当我准备停止它时,按Ctrl+c并没有正常关闭;它中断了Rake任务本身,它说rakeaborted!并给出堆栈跟踪。在某些情况下,我必须执行Ctrl+c两次。我可能可以用Signal.trap写一些东西来更优雅地中断它。有没有更简单的方法? 最佳答案 trap('SIGINT'){puts"Yourmessa

  10. ruby-on-rails - 如何播种图像的路径? - 2

    Organization和Image具有一对一的关系。Image有一个名为filename的列,它存储文件的路径。我在Assets管道中包含这样一个文件:app/assets/other/image.jpg。播种时如何包含此文件的路径?我已经在我的种子文件中尝试过:@organization=...@organization.image.create!(filename:File.open('app/assets/other/image.jpg'))#Ialsotried:#@organization.image.create!(filename:'app/assets/other/i

随机推荐