Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1743320
  • 博文数量: 143
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1462
  • 用 户 组: 普通用户
  • 注册时间: 2016-08-23 11:14
文章分类

全部博文(143)

文章存档

2022年(3)

2021年(13)

2020年(21)

2019年(8)

2018年(28)

2017年(7)

2016年(63)

我的朋友

分类: LINUX

2016-10-27 18:47:33

  在Linux下,安装某开发工具包或者执行某应用程序时,经常遇到“找不到共享库(.so)”的问题,如:error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory 。此时,如果执行ldd xxx查看此工具包或应用程序所依赖的共享库,发现确实有:某共享库(.so) => not found,然而此共享库(.so)实际在系统中已经存在了。那么,就需要将共享库(.so)路径添加到动态加载器(/lib/ld-linux.so.2)的查找路径下。根据以前博文中讲过的:在Linux下,动态加载器(/lib/ld-linux.so.2)是如何寻找程序所依赖的共享库(.so)的,相应的有以下3种解决方法:
  方法1:直接拷贝文件到Linux系统默认的库搜索路径,或在Linux系统默认的库搜索路径下为该共享库建立一个连接。通常Linux系统把/lib和/usr/lib两个目录作为默认的库搜索路径。
       cp libxxx.so /lib/.
       或
       ln -s `pwd`/libxxx.so /lib
  方法2:在/etc/ld.so.cache中增加库搜索路径。
       将共享库所在目录追加到共享库配置文件 /etc/ld.so.conf 中,然后执行共享库管理程序 ldconfig 更新到缓存文件 /etc/ld.so.cache 中:pwd >> /etc/ld.so.conf ; ldconfig 。
       或
       利用共享库管理程序 ldconfig ,强制更新共享库所在目录到缓存文件 /etc/ld.so.cache 中:ldconfig `pwd`。需要注意的是,这种临时解决方法一旦再次运行ldconfig(如重启系统)后,缓存文件 /etc/ld.so.cache 中的内容会被重新覆盖。
  方法3:在LD_LIBRARY_PATH中增加库搜索路径。
       在系统级别的/etc/profile中添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx 语句,然后执行点命令source /etc/profile 或 . /etc/profile 使不reboot即可生效:vim /etc/profile ; export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx ; source /etc/profile 。/etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。
       或
       在~/.bashrc中添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx 语句,然后执行点命令source ~/.bashrc 或 . ~/.bashrc 使不重新打开shell即可生效:vim ~/.bashrc ; export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx ; source ~/.bashrc 。~/.bashrc: 该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该文件被读取。
       或
       直接export LD_LIBRARY_PATH增加库搜索路径:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd` 。需要注意的是,直接使用export设置的变量都是临时变量,也就是说退出当前的shell后,为该变量定义的值便不在生效了。

  相应的,在Linux下,直接执行某工具或者应用程序时,也经常遇到“未找到命令”的问题,如:helloworld时出现"helloworld: command not found" 和 make da850_omapl138_defconfig ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-gcc时出现"make: arm-none-linux-gnueabi-gcc: command not found /bin/sh: arm-none-linux-gnueabi-gcc: command not found" 等等。这是因为,系统在当前用户的PATH路径下找不到该程序,和LD_LIBRARY_PATH一样,我们可以通过在PATH中增加搜索路径来解决,方法同与方法3。当然,也可以通过将该工具或应用程序拷贝到PATH的某一搜索路径下来解决。
  方法1:直接拷贝文件到PATH的某一搜索路径:cp helloworld /bin/.。
  方法2:在PATH中增加搜索路径。同于“方法3”

  然而,通常在Linux下,我们是通过sudo xxx执行某工具或者应用程序,此时虽然我们已经在PATH中增加了xxx所在路径,但仍然出现如上“未找到命令”的问题。当然,也会出现如上“找不到共享库(.so)”的问题,即使我们已经在LD_LIBRARY_PATH中增加了xxx所依赖库的所在路径,由于二者的根因是一样的,所以如下以“未找到命令”的问题为契机,来分析PATH。
  分析:首先,我们用echo $PATH 或env | grep PATH 查询当前用户的应用程序搜索路径,该工具或应用程序所在路径确实已经在PATH中了,那为什么呢?这是因为,通常当你在Ubuntu下用sudo管理权限提升执行权限而执行命令时,出于系统安全考虑,这个程序将在一个新的、最小化的环境中执行,也就是说,在sudo xxx时,系统将诸如PATH、LD_LIBRARY_PATH等环境变量重置成默认状态,而默认的PATH环境变量中不包含你所要运行程序的所在路径。不信,你用sudo env | grep PATH可以查询到,这个新的、最小化的PATH,里面确实没有该工具或应用程序所在路径。解决方法有2种:
  方法1:在sudo的配置文件/etc/sudoers中的secure_path后增加搜索路径,这个指令指定当用户执行 sudo 命令时在什么地方寻找命令。
       sudo visudo #打开sudo的配置文件
       修改secure_path。 #在默认PATH中,增加你所要运行程序的所在路径
       先Ctrl+o再Ctrl+x #保存退出。
  方法2:在sudo的配置文件/etc/sudoers中取消掉对PATH变量的重置,然后在~/.bashrc中配置“每次执行sudo命令时,将当前用户的的PATH变量传递给sudo的新的、最小化的环境中”。这样当用户用sudo执行命令时所搜寻的路径就是当前用户的PATH变量中的路径,如想添加其他变量如LD_LIBRARY_PATH也是类似。
       sudo visudo #打开sudo的配置文件
       修改Defaults env_reset为Defaults !env_reset。 #取消掉对PATH变量的重置
       先Ctrl+o再Ctrl+x #保存退出。
       vim ~/.bashrc #打开当前用户的.bashrc文件
       在~/.bashrc中最后添加alias sudo='sudo env PATH=$PATH'。 #将当前用户的PATH变量传递给sudo新的、最小化的环境中
       source ~/.bashrc #使之生效
  另外,需要注意的是:在Ubuntu下用sudo管理权限提升执行权限而执行命令时,既不是在root的环境下执行,也不是在当前用户的环境下执行,而是在一个新的、最小化的环境中执行。所以,单纯地想通过为root用户的环境变量增加搜索路径是不能解决问题的,博主也尝试了如下方法均不能成功:
  方法1:首先,通过export增加环境变量,即sudo export PATH=$PATH:your_project_path,但会出现"sudo: export: command not found",这种方法显然行不通。
  方法2:其次,通过su root切换到root用户,再gedit /etc/profile增加环境变量,这种方法也会报错。
  方法3:最后,ubuntu下编译时出现“make: arm-linux-gcc:命令未找到”的问题,这种方式虽不会报错但也不会生效。

注释:以上总结的每句话,博主都亲自在自己的Ubuntu系统上试验过了,打字不易,请珍惜。

参考文章
ldconfig命令和ldd命令详解
linux环境变量设置方法总结(PATH/LD_LIBRARY_PATH)
sudo找不到命令:修改sudo的PATH路径



阅读(10710) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~