bash 用于创建和 cd 到名称中包含空格的目录的脚本
bash script to create and cd to directory with spaces in name
我正在开发一个项目,以在我的 GitLab CE 实例中远程创建一个存储库(该部分正在运行!),然后使用项目名称创建一个目录(正在运行!)并 cd 进入该目录(这是我遇到问题的地方......)然后在本地初始化并添加远程存储库(工作!!!)
我遇到的问题只是更改到新目录。无论我使用下面显示的代码,还是只是尝试 cd ""
或 cd "$*"
,我似乎都无法让它工作!
#!/bin/bash
dir="$*"
wd=$(pwd)
fulldir="$(pwd)/${dir// /\ }/"
echo "Creating directory $dir"
mkdir -v "$dir"
cd "$dir"
echo "Changing current directory to $dir"
echo $dir
echo $fulldir
这段代码的输出是:
root@cana:~# ls
glnewproj test
root@cana:~# bash test Hello World
Creating directory Hello World
mkdir: created directory 'Hello World'
Changing current directory to Hello World
Hello World
/root/Hello\ World/
root@cana:~# ls
Hello World glnewproj test
root@cana:~# pwd
/root
如何 cd
进入我新创建的目录?我完全被难住了。
编辑:
键入每个 ghoti 的函数并在 .bashrc
和我的测试脚本中对其进行测试。
当运行函数直接来自bash:
root@cana:~# ls
glnewproj test test2
root@cana:~# mkcd "Hello World"
root@cana:~/Hello World#
当 运行 来自新测试脚本的函数时:
root@cana:~# ls
glnewproj test test2
root@cana:~# cat test2
#!/bin/bash
mkcd() {
mkdir -p "" && cd ""
}
mkcd ""
root@cana:~# bash test2 "Hello World"
root@cana:~# ls
Hello World glnewproj test test2
所以脚本仍然是 运行 的子脚本,因此不会更新父脚本 shell 的当前目录。我唯一的选择是在脚本末尾生成一个新的 shell 吗?
只要您按照问题中提到的那样使用 cd ""
,您的脚本(大部分)都很好。问题是您需要确保完整的目录名称实际上作为单个参数传递。
$ bash test "Hello World"
然后在你的脚本中
# Omitting unused $wd
# Omitting $fulldir, which appeared to be for debugging purposes only
dir=
mkdir -v "$dir"
cd "$dir"
经过更多研究,我发现这是因为脚本是一个子进程,不能影响父进程 shell。也就是说,该脚本将 cd 用于它自己的目的。例如,我可以将代码更改为以下内容:
#!/bin/bash
dir=
mkdir -v "$dir"
cd "$dir"
touch test.file
和运行
$ bash test "Hello World"
结果是文件 test.file
出现在 ./Hello\ World/
中,但是当脚本完成时,我仍会在之前的工作目录中。
获得我想要的结果的草率方法是 cd
到新目录,是使用 exec bash
.
在脚本中生成一个新会话
当您从 在脚本 中 cd
时,您的目录会在脚本中更改,但不会在调用 shell 中更改。交互式 shell 中的工作目录是由 THAT shell 中的 cd
命令设置的,而不是在它 运行 的程序中设置的。
如果您希望您的脚本能够更改您的交互式 shell 的目录,那么您可能需要设置一个 bash 函数.例如,可以将以下内容添加到您的 .bash_profile
:
mkcd() {
mkdir -p "" && cd ""
}
由于此函数 运行 在您的交互式 shell 的上下文中,而不是生成子 shell 或子进程,它所做的目录更改在退出后会保留.
另一种选择,如果您 need/want 使目录创建脚本成为一个独立的工具,那就是在 mktemp
之后建模,创建它需要的东西,然后 returns它创建到标准输出的名称。因此,使用以下脚本,可能称为 mkcd
:
#!/bin/bash
if mkdir -p "$*"; then
cd -P "$*"
pwd
r=0
else
r=$?
fi
exit $r
然后在您的调用脚本中,您可以运行这样:
#!/bin/bash
d=$(mkcd Hello World)
if [ ! -d "$d" ]; then
echo "ERROR: I can't go on like this" >&2
exit 1
fi
cd "$d"
: do your stuff
请注意,即使看起来多余,错误检查仍然是一个好主意,因为如果使用特殊字符或奇怪的格式来构建目录名称,则可能会成为意外或故意不可预测行为的受害者。
我正在开发一个项目,以在我的 GitLab CE 实例中远程创建一个存储库(该部分正在运行!),然后使用项目名称创建一个目录(正在运行!)并 cd 进入该目录(这是我遇到问题的地方......)然后在本地初始化并添加远程存储库(工作!!!)
我遇到的问题只是更改到新目录。无论我使用下面显示的代码,还是只是尝试 cd ""
或 cd "$*"
,我似乎都无法让它工作!
#!/bin/bash
dir="$*"
wd=$(pwd)
fulldir="$(pwd)/${dir// /\ }/"
echo "Creating directory $dir"
mkdir -v "$dir"
cd "$dir"
echo "Changing current directory to $dir"
echo $dir
echo $fulldir
这段代码的输出是:
root@cana:~# ls
glnewproj test
root@cana:~# bash test Hello World
Creating directory Hello World
mkdir: created directory 'Hello World'
Changing current directory to Hello World
Hello World
/root/Hello\ World/
root@cana:~# ls
Hello World glnewproj test
root@cana:~# pwd
/root
如何 cd
进入我新创建的目录?我完全被难住了。
编辑:
键入每个 ghoti 的函数并在 .bashrc
和我的测试脚本中对其进行测试。
当运行函数直接来自bash:
root@cana:~# ls
glnewproj test test2
root@cana:~# mkcd "Hello World"
root@cana:~/Hello World#
当 运行 来自新测试脚本的函数时:
root@cana:~# ls
glnewproj test test2
root@cana:~# cat test2
#!/bin/bash
mkcd() {
mkdir -p "" && cd ""
}
mkcd ""
root@cana:~# bash test2 "Hello World"
root@cana:~# ls
Hello World glnewproj test test2
所以脚本仍然是 运行 的子脚本,因此不会更新父脚本 shell 的当前目录。我唯一的选择是在脚本末尾生成一个新的 shell 吗?
只要您按照问题中提到的那样使用 cd ""
,您的脚本(大部分)都很好。问题是您需要确保完整的目录名称实际上作为单个参数传递。
$ bash test "Hello World"
然后在你的脚本中
# Omitting unused $wd
# Omitting $fulldir, which appeared to be for debugging purposes only
dir=
mkdir -v "$dir"
cd "$dir"
经过更多研究,我发现这是因为脚本是一个子进程,不能影响父进程 shell。也就是说,该脚本将 cd 用于它自己的目的。例如,我可以将代码更改为以下内容:
#!/bin/bash
dir=
mkdir -v "$dir"
cd "$dir"
touch test.file
和运行
$ bash test "Hello World"
结果是文件 test.file
出现在 ./Hello\ World/
中,但是当脚本完成时,我仍会在之前的工作目录中。
获得我想要的结果的草率方法是 cd
到新目录,是使用 exec bash
.
当您从 在脚本 中 cd
时,您的目录会在脚本中更改,但不会在调用 shell 中更改。交互式 shell 中的工作目录是由 THAT shell 中的 cd
命令设置的,而不是在它 运行 的程序中设置的。
如果您希望您的脚本能够更改您的交互式 shell 的目录,那么您可能需要设置一个 bash 函数.例如,可以将以下内容添加到您的 .bash_profile
:
mkcd() {
mkdir -p "" && cd ""
}
由于此函数 运行 在您的交互式 shell 的上下文中,而不是生成子 shell 或子进程,它所做的目录更改在退出后会保留.
另一种选择,如果您 need/want 使目录创建脚本成为一个独立的工具,那就是在 mktemp
之后建模,创建它需要的东西,然后 returns它创建到标准输出的名称。因此,使用以下脚本,可能称为 mkcd
:
#!/bin/bash
if mkdir -p "$*"; then
cd -P "$*"
pwd
r=0
else
r=$?
fi
exit $r
然后在您的调用脚本中,您可以运行这样:
#!/bin/bash
d=$(mkcd Hello World)
if [ ! -d "$d" ]; then
echo "ERROR: I can't go on like this" >&2
exit 1
fi
cd "$d"
: do your stuff
请注意,即使看起来多余,错误检查仍然是一个好主意,因为如果使用特殊字符或奇怪的格式来构建目录名称,则可能会成为意外或故意不可预测行为的受害者。