用于更改父 shell 目录的 Bash 脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13753157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash script to change parent shell directory
提问by michaelespinosa
What I'm trying to do
我想做什么
I've created a shell script that I've added to my $PATH that will download and get everything setup for a new Laravelproject. I would like the script to end by changing my terminal directory into the new project folder.
我已经创建了一个 shell 脚本,我已经将它添加到我的 $PATH 中,它将下载并为新的Laravel项目设置所有内容。我希望通过将终端目录更改为新项目文件夹来结束脚本。
From what I understand right now currently it's only changing the directory of the sub shell where the script is actually running. I can't seem to figure out how to do this. Any help is appreciated. Thank you!
根据我目前的理解,它只是更改脚本实际运行的子 shell 的目录。我似乎无法弄清楚如何做到这一点。任何帮助表示赞赏。谢谢!
#! /usr/bin/env bash
echo -e '3[1;30m=========================================='
## check for a directory
if test -z ""; then
echo -e ' 3[0;31m? Please provide a directory name'
exit
fi
## check if directory already exist
if [ ! -d ]; then
mkdir
else
echo -e ' 3[0;31m? The '""' directory already exists'
exit
fi
# move to directory
cd
## Download Laravel
echo -e ' 3[0;32m+ 3[0mDownloading Laravel...'
curl -s -L https://github.com/laravel/laravel/zipball/master > laravel.zip
## Unzip, move, and clean up Laravel
echo -e ' 3[0;32m+ 3[0mUnzipping and cleaning up files...'
unzip -q laravel.zip
rm laravel.zip
cd *-laravel-*
mv * ..
cd ..
rm -R *-laravel-*
## Make the /storage directory writable
echo -e ' 3[0;32m+ 3[0mMaking /storage directory writable...'
chmod -R o+w storage
## Download and install the Generators
echo -e ' 3[0;32m+ 3[0mInstalling Generators...'
curl -s -L https://raw.github.com/JeffreyWay/Laravel-Generator/master/generate.php > application/tasks/generate.php
## Update the application key
echo -e ' 3[0;32m+ 3[0mUpdating Application Key...'
MD5=`date +”%N” | md5`
sed -ie 's/YourSecretKeyGoesHere!/'"$MD5"'/' application/config/application.php
rm application/config/application.phpe
## Create .gitignore and initial git if -git is passed
if [ "" == "-git" ]; then
echo -e ' 3[0;32m+ 3[0mInitiating git...'
touch .gitignore
curl -s -L https://raw.github.com/gist/4223565/be9f8e85f74a92c95e615ad1649c8d773e908036/.gitignore > .gitignore
# Create a local git repo
git init --quiet
git add * .gitignore
git commit -m 'Initial commit.' --quiet
fi
echo -e '3[1;30m=========================================='
echo -e ' 3[0;32m? Laravel Setup Complete3[0m'
## Change parent shell directory to new directory
## Currently it's only changing in the sub shell
filepath=`pwd`
cd "$filepath"
采纳答案by DigitalRoss
Use a shell functionto front-end your script
使用 shell函数前端脚本
setup () {
# first, call your big script.
# (It could be open-coded here but that might be a bit ugly.)
# then finally...
cd someplace
}
Put the shell function in a shell startup file.
将 shell 函数放在一个 shell 启动文件中。
回答by sampson-chen
You can technically sourceyour script to run it in your parent shell instead of spawning a subshell to run it. This way whatever changes you make to your current shell (including changing directories) persist.
从技术上讲,您可以source将脚本在父 shell 中运行,而不是生成子 shell 来运行它。这样,您对当前 shell 所做的任何更改(包括更改目录)都会保持不变。
source /path/to/my/script/script
or
或者
. /path/to/my/script/script
But sourcing has its own dangers, use carefully.
但采购有其自身的危险,请谨慎使用。
(Peripherally related: how to use scripts to change directories)
(外围相关:如何使用脚本更改目录)
回答by yasu
Child processes (including shells) cannot change current directory of parent process. Typical solution is using eval in the parent shell. In shell script echo commands you want to run by parent shell:
子进程(包括 shell)不能改变父进程的当前目录。典型的解决方案是在父 shell 中使用 eval。在您希望由父 shell 运行的 shell 脚本 echo 命令中:
echo "cd $filepath"
In parent shell, you can kick the shell script with eval:
在父 shell 中,您可以使用 eval 启动 shell 脚本:
eval `sh foo.sh`
Note that all standard output will be executed as shell commands. Messages should output to standard error:
请注意,所有标准输出都将作为 shell 命令执行。消息应该输出到标准错误:
echo "Some messages" >&2
command ... >&2
回答by twalberg
I suppose one possibility would be to make sure that the only output of your script is the path name you want to end up in, and then do:
我想一种可能性是确保脚本的唯一输出是您想要结束的路径名,然后执行以下操作:
cd `/path/to/my/script`
There's no way your script can directly affect the environment (including it's current directory) of its parent shell, but this would request that the parent shell itself change directories based on the output of the script...
您的脚本无法直接影响其父 shell 的环境(包括它的当前目录),但这会要求父 shell 本身根据脚本的输出更改目录...
回答by Ignacio Vazquez-Abrams
This can't be done. Use execto open a new shell in the appropriate directory, replacing the script interpreter.
这是做不到的。用于exec在适当的目录中打开一个新的 shell,替换脚本解释器。
exec bash

