Linux 创建bash脚本并将其cd到名称中带有空格的目录
我正在做一个项目,在我的GitLab CE实例中远程创建一个存储库(该部分正在工作!),然后使用项目名称(工作!)和cd在该目录中创建一个目录(这里是我遇到问题的地方…),然后在本地初始化并添加远程存储库(工作!!!) 我遇到的问题仅仅是转换到新目录。无论我是使用下面显示的代码,还是仅仅尝试Linux 创建bash脚本并将其cd到名称中带有空格的目录,linux,bash,unix,mkdir,cd,Linux,Bash,Unix,Mkdir,Cd,我正在做一个项目,在我的GitLab CE实例中远程创建一个存储库(该部分正在工作!),然后使用项目名称(工作!)和cd在该目录中创建一个目录(这里是我遇到问题的地方…),然后在本地初始化并添加远程存储库(工作!!!) 我遇到的问题仅仅是转换到新目录。无论我是使用下面显示的代码,还是仅仅尝试cd“$1”或cd“$*”我似乎根本无法让它工作 #!/bin/bash dir="$*" wd=$(pwd) fulldir="$(pwd)/${dir// /\\ }/&q
cd“$1”
或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 "$1" && cd "$1"
}
mkcd "$1"
root@cana:~# bash test2 "Hello World"
root@cana:~# ls
Hello World glnewproj test test2
因此,脚本仍作为子脚本运行,因此不会更新父shell的当前目录。在脚本末尾生成新shell是我唯一的选择吗?您的脚本(大部分)很好,只要您使用问题中提到的cd“$1”
。问题是,您需要确保完整的目录名实际上是作为单个参数传递的
$ bash test "Hello World"
然后在你的剧本里
# Omitting unused $wd
# Omitting $fulldir, which appeared to be for debugging purposes only
dir=$1
mkdir -v "$dir"
cd "$dir"
通过进一步研究,我发现这是因为脚本是一个子进程,不能影响父shell。也就是说,脚本将为自己的目的而保存cd。例如,我可以将代码更改为以下内容:
#!/bin/bash
dir=$1
mkdir -v "$dir"
cd "$dir"
touch test.file
跑
$bash测试“Hello World”
结果将是出现在/Hello\World/
中的文件test.file
,但是当脚本完成时,我仍将在以前的工作目录中
获得我想要的结果的一种草率方法是将
cd
放入新目录,即使用exec bash
在脚本中生成一个新会话。当您从脚本中cd
时,您的目录在脚本中更改,但在调用shell中没有更改。交互式shell中的工作目录是由该shell中的cd
命令设置的,而不是由它运行的程序内部设置的
如果希望脚本能够更改交互式shell的目录,则可能需要设置bash函数。例如,可以将以下内容添加到.bash\u配置文件中:
mkcd() {
mkdir -p "$1" && cd "$1"
}
由于此函数在交互式shell的上下文中运行,而不是生成子shell或子进程,因此它所做的目录更改将在退出后保留
如果您需要/想要使目录创建脚本成为一个独立的工具,另一个选项是在mktemp
之后建模,这将创建它需要的内容,然后将它创建的内容的名称返回给stdout。因此,使用以下脚本,可能称为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
请注意,即使错误检查看起来是多余的,它仍然是一个好主意,因为如果使用特殊字符或奇数格式来构建目录名,可能会成为意外或故意不可预测行为的受害者。不幸的是,这也不会改变我的目录。因此,这应该放在中。bashrc
是吗?然后,当从脚本运行时,它应该在脚本之外运行,我可以避免在每个回答中产生惊人数量的会话锁定你的.bashrc
将起作用,或者锁定你的.bash\u档案
,如果这是为了交互使用。例如,要在从cron运行的脚本中使用,只需将其添加到脚本的顶部即可。我不确定你的用例,我们可能会把它变成一个…我遇到了一些奇怪的行为。我已经将它添加到.bashrc
中,如果我直接从shell运行函数,则会得到所需的结果,但是如果我将其作为脚本运行,脚本仍在执行它,并且不会影响父shell。您如何从脚本中调用它?也许你可以用这些实验和结果更新你的问题。用更多信息更新了问题。你的test2
脚本仍然是一个单独的脚本,没有在你的交互式shell中运行。test2内部有自己的函数名为mkcd
,这一事实并没有改变它运行在通过在交互式shell中运行bash
创建的子shell中的事实。不要运行`bash test2“Hello World”,而是将test2作为运行shell中的一个函数,然后运行该函数。然而,我试图做的完全取决于它是一个脚本。好吧,现在您有了多个答案,包括您自己的答案,并且您理解为什么您会遇到问题。如果您真的希望能够将交互式shell中的目录更改为脚本创建的目录,那么有多种方法可以将其组合在一起,我在回答中已经描述了一种方法。考虑到你问题的详细程度,我不可能知道它是否适用于你。