安装oh-my-zsh报错could not create work tree dir '/root/.oh-my-zsh'.: Permission denied的原因解决办法
前言
linux新手可能会通过su
方式切换用户,但没有意识到环境变量没有切换,导致一些奇葩问题,这里便是一个例子,值得记录。
笔者在切换linux用户使用ZSH
时遇到问题,确切来说是切换用户后安装oh-my-zsh
时遇到问题。
问题出现的根本原因在切换用户方式上,我是通过su 某用户
切换用户,而这样切换用户,环境变量仍是切换前用户的!
关于切换用户环境变量是否随之切换看这里解析。
- 熟悉linux的朋友:只需看问题,原因,解决办法即可。
- 新手:可以看下完整解决过程。个人认为,遇到问题->解决问题的过程才是最重要的,知道问题的答案去理解都不难,关键是由不懂到懂的过程。
问题
背景:linux下,zsh已成功安装,某个用户的oh-my-zsh也已成功安装,能正常使用。
可能,你刚新添加了一个用户,想这个用户也能使用zsh;可能你因某个需求要切换到某个用户,切换后发现其shell不是zsh或用起来不方便,想这个用户也能方便使用zsh。总之,你通过su A用户
切换到A用户,然后开始
安装
oh-my-zsh
,执行指令sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
遇到类似以下报错:
Cloning Oh My Zsh... fatal: could not create work tree dir '/root/.oh-my-zsh'.: Permission denied Error: git clone of oh-my-zsh repo failed
疑似权限问题,你尝试加
sudo
解决sudo sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
然后报已安装错误
You already have Oh My Zsh installed. You'll need to remove /root/.oh-my-zsh if you want to re-install.
原因
首先,明确一点:oh-my-zsh
相关文件是每个用户独有的,不是所有用户共用一份的。
第一个报错:
- 安装脚本
install.sh
文件内容:判断$ZSH
是否有值,有值,访问其指代的目录文件,没问题则打印你已安装;权限问题访问不了则权限错误;无值,则将相关文件安装在~/.oh-my-zsh
,并export ZSH=~/.oh.-my-zsh
。 - 通过
su
切换用户,环境变量并未随之改变,$ZSH
变量为切换前用户的对应值,以切换前用户为root为例,echo $ZSH
,显示/root/.oh-my-zsh
。
综上,当前用户并未安装
oh-my-zsh
,但安装脚本根据前一个用户的$ZSH
以为当前用户已安装,但没权限访问,因此报权限错误。- 安装脚本
第二个报错:加上sudo后,有了访问
/前一个用户家目录/.oh-my-zsh
目录的权限,访问发现确实存在,就报已安装,需要删除后才能重新安装。
综上,根本原因是环境变量没有随用户切换而切换。
su 用户 :只切换身份
su - 用户 :身份和shell(包含环境变量)都切换
解决办法
对安装oh-my-zsh
来说,关键在于$ZSH
变量,只要清空之即可,下面两种方式均可:
手动清空
$ZSH
变量ZSH= ## 查看是否清空成功 echo $ZSH
ctrl + d
退回能最开始的用户,通过su -
切换su - 期望用户 ## 查看一下 echo $ZSH
然后执行下载安装
sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
输出以下内容,表示成功
__ __ ____ / /_ ____ ___ __ __ ____ _____/ /_ / __ \/ __ \ / __ `__ \/ / / / /_ / / ___/ __ \
/ /_/ / / / / / / / / / / /_/ / / /_(__ ) / / /
\____/_/ /_/ /_/ /_/ /_/\__, / /___/____/_/ /_/ /____/ ....is now installed!Please look over the ~/.zshrc file to select plugins, themes, and options.p.s. Follow us at https://twitter.com/ohmyzsh.p.p.s. Get stickers and t-shirts at https://shop.planetargon.com.
安装成功后,查看$ZSH
的值,验证上述说法
echo $ZSH
## 输出
/home/当前用户家目录/.oh-my-zsh
熟悉linux的朋友不用往下看了,很啰嗦的~
解决过程
首先,我是通过root用户连接到服务器的,安装,使用zsh,oh-my-zsh一切顺利,因某个需求要切换到test用户
su test
,发现没有zsh效果,echo $SHELL
,是bash…,原来是忘了修改test用户的默认shell,切换回root用户,
vim /etc/passwd
,修改并保存test:x:1007:1007::/home/test:/bin/bash ## 改为 test:x:1007:1007::/home/test:/bin/zsh
切换到test用户,
echo $SHELL
,变为zsh了。然而一点也不方便,并且没有炫酷的终端效果——颜色变化,猜测是没有oh-my-zsh
,心想,原来好用的是oh-my-zsh!安装之,一条命令而已sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
然后就报权限错误:
Cloning Oh My Zsh... fatal: could not create work tree dir '/root/.oh-my-zsh'.: Permission denied Error: git clone of oh-my-zsh repo failed
权限问题,加个sudo看看吧
sudo sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
提示我test用户不在sudo列表里,不能使用sudo,
test is not in the sudoers file. This incident will be reported.
添加之
su root ## 切换到root用户 chmod u+w /etc/sudoers ## 添加sudoers文件所属用户的写入权限 vim /etc/sudoers ## 添加如下内容 test ALL=(ALL) ALL chmod u-w /etc/sudoers ## 添加完成删除写入权限,保证安全
再执行一次安装指令。报oh-my-zsh已安装…,额,已安装你倒是让我test用户使用啊…
You already have Oh My Zsh installed. You'll need to remove /root/.oh-my-zsh if you want to re-install.
分析
难道要删除
/root/.oh-my-zsh
?,但删除了root用户怎么使用呢?首先要确认
oh-my-zsh
相关文件像指令一样给所有用户共用,还是像配置文件一样每个用户独有?- 如果是共用的,不应该默认安装在
root
家目录下啊(我没改任何配置),其它用户去访问root
家目录,即使放开权限能行,始终是不合适的(何况我试过把/root/.oh-my-zsh权限设为777
,还是不行)。 - 得出结论:
oh-my-zsh
相关文件是每个用户独有的。 - 结论推导是:在test用户下安装
oh-my-zsh
,会在test用户家目录添加oh-my-zsh
相关文件。
但现在的确是在test用户下,执行github上
oh-my-zsh
给的安装指令,却报root家目录下oh-my-zsh
相关文件权限错误。难道问题出在安装指令上?安装指令指定了安装到哪个目录吗?- 如果是共用的,不应该默认安装在
分析安装指令,上网查得
sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
sh命令
是shell命令语言解释器,-c
指从-c
后的字符串读取;$()
简单理解是将执行括号里代码得到的结果返回wget
是下载 指定url的文件(默认指下载,不打印,与curl相反),-O
后接保存到本地的文件名,用-O -
表示将文件内容打印,不保存到本地文件通过与curl比较,更好理解wget使用,链接
最终得到的就是执行了
install.sh
脚本文件,并没有通过安装指令指定文件安装位置。分析
install.sh
脚本下载
install.sh
文件来看看内容吧,shell脚本,也是代码而已。wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh vim install.sh
太大段就不全贴上来了,根据报错
Error: git clone of oh-my-zsh repo failed
,在install.sh
搜索到env git clone --depth=1 https://github.com/robbyrussell/oh-my-zsh.git $ZSH || {printf "Error: git clone of oh-my-zsh repo failed\n"exit 1}
再搜一下,
You already have Oh My Zsh installed.
,内容如下if [ -d "$ZSH" ]; thenprintf "${YELLOW}You already have Oh My Zsh installed.${NORMAL}\n"printf "You'll need to remove $ZSH if you want to re-install.\n"exitfi
都有
$ZSH
变量!且文件中多次出现$ZSH
再次分析
按上面的分析,
oh-my-zsh
相关文件是每个用户独有的,那么- 安装脚本理应根据当前用户是谁,来把相关文件安装到谁的家目录;
- 如果当前用户已安装,安装脚本能识别出来,要求他删除后才能再次安装。
经查看,
install.sh
脚本的内容正是如此,具体到安装脚本通过什么来识别,就是$ZSH
变量,如果$ZSH
为空,文件内容如下:if [ ! -n "$ZSH" ]; thenZSH=~/.oh-my-zshfi## 把ZSH设为环境变量了export ZSH=$ZSH
如果
$ZSH
有值,则输出已安装,要先删除$ZSH
指代的文件才能再次安装。到这里,就很明显了,根据报错提示,test用户的
$ZSH
变量是/root/.oh-my-zsh
,查看一下,确实是这样。echo $ZSH /root/.oh-my-zsh
解决:
清空ZSH变量,执行下载安装命令,安装成功后,查看$ZSH
变量
ZSH=
sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
echo $ZSH
## 显示
/home/test/.oh-my-zsh
至此,安装成功,问题解决。
总结
切换用户
su 用户
:只切换身份su - 用户
:切换身份和shell(保护环境变量)
linux下载安装指令
wget
:默认只下载,-O 文件名
指定保存文件名,-O -
打印文件内容不保存为文件。curl
:默认只打印,-O
保存为文件- 常伴随出现的:
sh -c
,$()
一点体会:遇到问题,不要躲。
很早就出现切换用户无法正常使用
zsh
问题,开始是通过尽量不切换用户来避开它,但到了必须切换时,例如不能通过root用户使用composer…,就很烦,心里不踏实,切换用户后一遇到报错,总会怀疑是否与所切换用户无法正常使用zsh
有关。如果总是积累这那么多不确定,往下走,好累!
相关链接
- linux 中切换用户:su和su -的使用环境变量详解
oh-my-zsh
下载地址- curl和wget的区别和使用
安装oh-my-zsh报错could not create work tree dir '/root/.oh-my-zsh'.: Permission denied的原因解决办法相关推荐
- 【已解决】启动Python报错api-ms-win-crt-process-l1-1-0.dll缺失,windows7无法升级,升级补丁打不上的解决办法
[已解决]启动Python报错api-ms-win-crt-process-l1-1-0.dll缺失,windows7无法升级,升级补丁打不上的解决办法 问题:启动python报错api-ms-win ...
- python报错:xml.parsers.expat.ExpatError: not well-formed (invalid token): line 3, column 1的解决办法
本篇文章主要讲解,python报错:xml.parsers.expat.ExpatError: not well-formed (invalid token): line 3, column 1的解决 ...
- 【庖丁解牛】成功解决nginx报错:bind() to 0.0.0.0:8090 failed (13: Permission denied)
文章目录 错误复现 错误原因 解决方案 错误复现 在nginx设置基于端口的虚拟主机的时候,设定两个端口,一个是80,一个是8090, 在重启nginx的时候 [root@zmedu-17 rpm]# ...
- 如何安装kaggle API下载数据 及报错OSError: Could not find kaggle.json. Make sure it‘s located in /home/user/解决办法
如何安装kaggle API下载数据 及报错OSError: Could not find kaggle.json. Make sure it's located /解决办法 C:\Users\pc& ...
- 启动项目,报错:The server selected protocol version TLS10 is not accepted by client preferences [TLS12]解决办法
使用idea加载刚down下来的项目启动时,报错:The server selected protocol version TLS10 is not accepted by client prefer ...
- mysql启动报错: 某些服务在未由其他服务器或程序使用时即将自动停止-解决办法
第一步:进入到 DOS窗口,按windows+r用管理员登录C:\Windows\system32>是这种操作界面 第二步:E:\>cd E:\mysq ...
- Qt编译报错:usr/include/c++/4.9/bits/stl_relops.:67: Parse error at “std“的解决办法
明明安装了gcc和g++,版本是4.9.2 系统debian8 qmake -v qmake myproject.pro 无任何报错 make 编译没有问题,链接的时候报错: /usr/local/ ...
- 加载MNIST报错:[WinError 10060] 由于连接方在一段时间后没有正确答复解决办法(亲测)
转载:https://blog.csdn.net/landcruiser007/article/details/79346982 tensorflow加载mnist数据集,一些书上和博客中的代码如下: ...
- 类中调用界面ActiveX控件报错当前线程不在单线程单元中因此无法实例化 ActiveX 控件的解决办法...
解决办法是Form类中定义一个静态的ActiveX对象,在formload中将界面上的ActiveX对象赋值给新定义的对象,类中访问该静态对象即可. public static AxClientDri ...
最新文章
- pip通过阿里源安装
- 用VC写Assembly代码(5) --函数调用(三)
- linux qt3编译出错,Linux下编译Qt 5版本源码
- show processlis
- python图片转excel,Python代码,将图片转为了Excel
- plsql 通过 excel 创建表
- creo 6.0—02:单位的设置,默认绘图模板的绘制(重点)
- 旅行社H5广告宣传怎么做?
- 33. Prometheus-报警-通知模板参考
- 企业微信预览图片的接口使用wx.previewImage
- 用例图(use case diagram)
- ssm毕设项目酒店管理系统08281(java+VUE+Mybatis+Maven+Mysql+sprnig)
- ubuntu 关闭系统自动更新
- 大胆预测一下《数据结构》期末机考题
- Vue动画出现和隐藏
- 六个办公常用的网站,让你大开眼界的网站
- 【厚积薄发系列】C++项目总结19—组件化架构思想
- HTML——表单及表单元素
- 两道大众点评网技术部的笔试题
- intouch的服务器修改密码后,intouch登录设置
热门文章
- AutoCAD C# 多段线自相交检测
- 安装ttf-mscorefonts-installer的方法
- 计算机调剂光学工程,山东大学2020研究生调剂信息-光学工程/材料科学与工程
- 两个日期之间的天数--【编程珠玑】
- 用1个拨码开关控制所有的LED灯亮灭
- mysql添加普通索引_mysql在建表语句中添加索引
- IntelliJ Idea 2017 免费激活方法(亲测有效,可以尝试一下)
- 「第十二章」Web框架安全
- java进行图片合成以及写入自定义字体
- ubuntu下搭建android开发环境(四)核心篇安装AndroidStudio、sdk、jdk