尝试编写一个 bash 脚本(在 Mac 上),创建一个文件夹,然后在该文件夹中运行一堆脚本。我想回显文件夹的绝对路径,并在采取行动之前提示用户确认。
该脚本以相对路径作为参数,如何在创建文件夹之前转换为绝对路径?
!/bin/bash
if [[ $# -eq 0 ]] ; then
echo 'Whoa! You dont want to do that! you need to tell me where to put it'
exit 0
fi
ORG_DIR=$(pwd)
#here I want to get path before making directory, I've only figured out how to do after.
mkdir ../$1
cd ../$1
NEW_DIR=$(pwd)
echo "Running scripts in"
echo $NEW_DIR
read -p "Are you sure? (y/n) " -n 1 -r
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
# run a bunch of scripts
fi
如何在创建 NEW_DIR 之前获取它的绝对路径?
注意:平台是 OSX,我不需要支持其他 'nix 变体。
编辑:星期六,29
我意识到,为了将问题精简到仅包含必要的细节,我精简了太多内容,对此我深表歉意。
该脚本存在于(例如 sake)
/Documents/git/ProjectGenerator
我希望脚本在(或输入的任何路径)中生成一个项目
/Documents/git/NewProject
它运行 npm 脚本,并从
/Documents/git/ProjectGenerator
脚本的其余部分现在运行良好,但是我最近不小心按了错误的目录上的 Enter 键。由于此脚本仅供我使用(而不是 sudo),因此我尝试在脚本开头添加健全性检查,而不是安全检查。查看目录后必须键入 Y 并按 Enter。
我正在尝试获取一条绝对路径,而我得到的是
/Documents/git/ProjectGenerator/../NewProject
我试图让它回响
/Documents/git/NewProject
在创建目录之前。(有时路径要复杂得多)
在节点中我们有path.resolve(path)
在php或c中它的realpath(path)
我似乎无法在 osx bash 中找到等效的命令,有吗?或者我需要解析字符串?
答案1
您想使用 更改到上一个目录,..
但这会导致无法找出新目录($1
在您的脚本中命名,我将$new_directory_name
在这里调用它)的绝对路径../$new_directory_name
。
在执行任何cd
或之前mkdir
,我会使用basename
命令显示原始目录的$PWD
绝对路径,然后附加$new_directory_name
到它,如下所示:
echo $(dirname $PWD)/$new_directory_name
(或者$(...)
用反引号“...”替换命令替换(它们有时在 stackexchange 上显示很有趣 - 请参阅命令替换部分man bash
我相信你可以只使用 bash 的参数扩展(也在man bash
)$PWD
而不是basename
像这样:
echo ${PWD%/*}/$new_directory_name
例子
$ new_directory_name=newdir
$ pwd
/tmp/testdir
$ echo ${PWD%/*}/$new_directory_name
/tmp/newdir
$ echo $(dirname $PWD)/$new_directory_name
/tmp/newdir
就像 user912264 提到的那样,您可以考虑检查是否..
是可写目录(使用stat -c %a
或%A
),或者如果您已经进入/
则cd ..
不会去任何新地方,或者只是观察 中的错误mkdir
,例如
mkdir ... || { echo mkdir ERROR exiting; exit; }
答案2
来自 Stack Overflow 上的这条评论 https://stackoverflow.com/questions/284662/how-do-you-normalize-a-file-path-in-bash#comment81662652_284671
我得出的结论是 coreutils(我已经安装)具有greadlink
我需要的功能的命令。
NEW_DIR=$(greadlink -f ../$1)
编辑1:
#!/bin/bash
if [[ $# -eq 0 ]] ; then
#simple check to ensure enter was not accidently pressed without directory specified
echo 'Whoa! You dont want to do that! you need to tell me where to put it';
exit 0
fi
ORG_DIR=$(pwd)
#here I want to get path before making directory, I've only figured out how to do after.
NEW_DIR=$(greadlink -f ../$1)
echo "Running scripts in"
echo $NEW_DIR
read -p "Are you sure? (y/n) " -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
cp -r $ORG_DIR/skeleton $NEW_DIR
cd $NEW_DIR
#init the project with default answers.
yarn init -y
#add dev scripts
yarn add --dev webpack webpack-cli babel-loader @babel/preset-react @babel/core @babel/preset-env webpack-dev-server css-loader sass-loader node-sass style-loader file-loader url-loader redux-devtools eslint eslint-plugin-react babel-eslint
#add production scripts
yarn add react react-dom react-hot-loader react-redux redux redux-saga redux-socket.io socket.io
fi
答案3
回答标题中的问题
获取尚不存在的文件夹的绝对路径[bash]
使用realpath -s
或readlink -m
获取不存在文件的绝对路径
$ ( cd /tmp && realpath -s no/such/file )
/tmp/no/such/file
$ ( cd /tmp && readlink -m no/such/file )
/tmp/no/such/file
默认情况下,如果文件不存在,则realpath
和都会失败readlink
也可以看看如何在 Bash 中规范化文件路径?