2012年8月23日星期四

在Linux里设置环境变量的方法(export PATH)

http://www.cnblogs.com/amboyna/archive/2008/03/08/1096024.html

在Linux里设置环境变量的方法(export PATH)

一般来说,配置交叉编译工具链的时候需要指定编译工具的路径,此时就需要设置环境变量。例如我的mips-linux-gcc编译器在“/opt/au1200_rm/build_tools/bin”目录下,build_tools就是我的编译工具,则有如下三种方法来设置环境变量:

1、直接用export命令:
#export PATH=$PATH:/opt/au1200_rm/build_tools/bin查看是否已经设好,可用命令export查看:[root@localhost bin]# exportdeclare -x BASH_ENV="/root/.bashrc"
declare -x G_BROKEN_FILENAMES="1"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="localhost.localdomain"
declare -x INPUTRC="/etc/inputrc"
declare -x LANG="zh_CN.GB18030"
declare -x LANGUAGE="zh_CN.GB18030:zh_CN.GB2312:zh_CN"
declare -x LESSOPEN="|/usr/bin/lesspipe.sh %s"
declare -x LOGNAME="root"
declare -x LS_COLORS="no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:"
declare -x MAIL="/var/spool/mail/root"
declare -x OLDPWD="/opt/au1200_rm/build_tools"
declare -x PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin:/opt/au1200_rm/build_tools/bin"
declare -x PWD="/opt/au1200_rm/build_tools/bin"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_ASKPASS="/usr/libexec/openssh/gnome-ssh-askpass"
declare -x SSH_AUTH_SOCK="/tmp/ssh-XX3LKWhz/agent.4242"
declare -x SSH_CLIENT="10.3.37.152 2236 22"
declare -x SSH_CONNECTION="10.3.37.152 2236 10.3.37.186 22"
declare -x SSH_TTY="/dev/pts/2"
declare -x TERM="linux"
declare -x USER="root"
declare -x USERNAME="root"

可以看到,环境变量已经设好,PATH里面已经有了我要加的编译器的路径。

2、修改profile文件: 
#vi /etc/profile 
在里面加入:
export PATH="$PATH:/opt/au1200_rm/build_tools/bin"

3. 修改.bashrc文件:
# vi /root/.bashrc
在里面加入:
export PATH="$PATH:/opt/au1200_rm/build_tools/bin"

后两种方法一般需要重新注销系统才能生效,最后可以通过echo命令测试一下:
# echo $PATH
看看输出里面是不是已经有了/my_new_path这个路径了。

-----------------------------------------------------------------------------------------------------------------------
 “/bin”、“/sbin”、“/usr/bin”、“/usr/sbin”、“/usr/local/bin”等路径已经在系统环境变量中了,如果可执行文件在这几个标准位置,在终端命令行输入该软件可执行文件的文件名和参数(如果需要参数),回车即可。
  如果不在标准位置,文件名前面需要加上完整的路径。不过每次都这样跑就太麻烦了,一个“一劳永逸”的办法是把这个路径加入环境变量。命令 “PATH=$PATH:路径”可以把这个路径加入环境变量,但是退出这个命令行就失效了。要想永久生效,需要把这行添加到环境变量文件里。有两个文件可 选:“/etc/profile”和用户主目录下的“.bash_profile”,“/etc/profile”对系统里所有用户都有效,用户主目录下 的“.bash_profile”只对这个用户有效。
  “PATH=$PATH:路径1:路径2:...:路径n”,意思是可执行文件的路径包括原先设定的路径,也包括从“路径1”到“路径n”的所 有路径。当用户输入一个一串字符并按回车后,shell会依次在这些路径里找对应的可执行文件并交给系统核心执行。那个“$PATH”表示原先设定的路径 仍然有效,注意不要漏掉。某些软件可能还有“PATH”以外类型的环境变量需要添加,但方法与此相同,并且也需要注意“$”。
  注意,与DOS/Window不同,UNIX类系统环境变量中路径名用冒号分隔,不是分号。另外,软件越装越多,环境变量越添越多,为了避免造成混乱,建议所有语句都添加在文件结尾,按软件的安装顺序添加。
  格式如下():
  # 软件名-版本号
  PATH=$PATH:路径1:路径2:...:路径n
  其他环境变量=$其他环境变量:...
  在“profile”和“.bash_profile”中,“#”是注释符号,写在这里除了视觉分隔外没有任何效果。
  设置完毕,注销并重新登录,设置就生效了。如果不注销,直接在shell里执行这些语句,也能生效,但是作用范围只限于执行了这些语句的shell。
  相关的环境变量生效后,就不必老跑到软件的可执行文件目录里去操作了

linux中用C语言对环境变量设置

http://blog.csdn.net/xwdok/article/details/619728



getenv(取得环境变量内容)
相关函数
putenv,setenv,unsetenv
表头文件
#include<stdlib.h>
定义函数
char * getenv(const char *name);
函数说明
getenv()用来取得参数name环境变量的内容。参数name为环境变量的名称,如果该变量存在则会返回指向该内容的指针。环境变量的格式为name=value。
返回值
执行成功则返回指向该内容的指针,找不到符合的环境变量名称则返回NULL。
范例
#include<stdlib.h>
mian()
{
char *p;
if((p = getenv(“USER”)))
printf(“USER=%s/n”,p);
}
执行
USER = root



putenv(改变或增加环境变量)
相关函数
getenv,setenv,unsetenv
表头文件
#include4<stdlib.h>
定义函数
int putenv(const char * string);
函数说明
putenv()用来改变或增加环境变量的内容。参数string的格式为name=value,如果该环境变量原先存在,则变量内容会依参数string改变,否则此参数内容会成为新的环境变量。
返回值
执行成功则返回0,有错误发生则返回-1。
错误代码
ENOMEM 内存不足,无法配置新的环境变量空间。
范例
#include<stdlib.h>
main()
{
char *p;
if((p = getenv(“USER”)))
printf(“USER =%s/n”,p);
putenv(“USER=test”);
printf(“USER+5s/n”,getenv(“USER”));
}
执行
USER=root
USER=root



setenv(改变或增加环境变量)
相关函数
getenv,putenv,unsetenv
表头文件
#include<stdlib.h>
定义函数
int setenv(const char *name,const char * value,int overwrite);
函数说明
setenv()用来改变或增加环境变量的内容。参数name为环境变量名称字符串。
参数
value则为变量内容,参数overwrite用来决定是否要改变已存在的环境变量。如果overwrite不为0,而该环境变量原已有内容,则原内容 会被改为参数value所指的变量内容。如果overwrite为0,且该环境变量已有内容,则参数value会被忽略。
返回值
执行成功则返回0,有错误发生时返回-1。
错误代码
ENOMEM 内存不足,无法配置新的环境变量空间
范例
#include<stdlib.h>
main()
{
char * p;
if((p=getenv(“USER”)))
printf(“USER =%s/n”,p);
setenv(“USER”,”test”,1);
printf(“USER=%s/n”,getenv(“USEr”));
unsetenv(“USER”);
printf(“USER=%s/n”,getenv(“USER”));
}
执行
USER = root
USER = test
USER = (null)

shell脚本和sqlplus间的交互

http://www.ms2006.com/archives/99


有些时候我们可能需要shell脚本通过oracle的sqlplus执行一些sql,并对结果集进行相关的操作。这里大致总结有如下几种方法
  • 直接获取单个值
  • 1
    2
    3
    4
    5
    6
    7
    
    #!/bin/bash
    result=`sqlplus -S system/password <<EOF
    set heading off feedback off pagesize 0 verify off echo off numwidth 4
    select 1 from dual;
    exit
    EOF`
    echo $result #将返回sql执行的结果
  • 将shell的参数传递给sqlplus
  • 1
    2
    3
    4
    5
    6
    
    #!/bin/bash
    TEST="table_name"
    sqlplus -S system/password <<EOF
    select * from user_tables where table_name = upper('$TEST');
    exit
    EOF
  • sqlplus的结果含有多个列值
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    #使用上篇日志的例子
    result=`sqlplus -S system/password <<EOF
    set heading off feedback off pagesize 0 verify off echo off numwidth 4
    select t2.used,t1.maxsize from (select count(file_name)*32 maxsize from dba_data_files where tablespace_name ='$TBS_NAME') t1,(select trunc(sum(bytes)/1024/
    1024/1024) used from dba_data_files where tablespace_name='$TBS_NAME') t2;
    exit
    EOF`
     
    USED=`echo $result |cut -d " " -f1`
    MAXSIZE=`echo $result |cut -d " " -f2`
    最后两行就是对多结果集的处理,该查询语句将返回两列。不管是两列还是多列。系统都是用空格作为分隔符的顺序输出。所以我们通过上面两行就可以取到需要的值。如果列数或行数较多,可以使用其他方法,如for等。
    但是一定要注意,返回的结果集数据里面本身是否就含有空格~不要造成无伤

    shell脚本与c语言对比学习

    http://blog.csdn.net/xj178926426/article/details/6923745


    最近由于工作的关系,粗略的接触到一点脚本,之前也接触过,只是之前没有写过,只是偶尔自己加几句话怎么的。今天自己动手写啦一下,把shell对比于C语言的一些不同写在这里,当作自己学习的一个笔记,如果有不足之处还望各位牛人指出。
               不说这么多的废话吧,还是直接上代码:
    [plain] view plaincopy
    1. #!/bin/sh  
    2. start_command()  
    3. {  
    4.         echo "the first argument is :" $1   
    5.         do_it()  
    6.         {  
    7.                 local rc=0  
    8.                 echo "I just test !"  
    9.                 echo "Input Error !"  
    10.         }  
    11.         while [ 1 ] ; do  
    12.         read finished  
    13.         case $finished in  
    14.         1) echo "your input is 1 !" ;;  
    15.         2) echo "your input is 2 !" ;;  
    16.         q) echo "quit successful !"   
    17.            break ;;  
    18.         *) do_it ;;  
    19.         esac  
    20.         done  
    21. }  
    22.   
    23. start_command "hello world !"  
    24. exit 0  

     
    程序运行的结果:
    [plain] view plaincopy
    1. the first argument is : hello world !  
    2. 1  
    3. your input is 1 !  
    4. 2  
    5. your input is 2 !  
    6. 3  
    7. I just test !  
    8. Input Error !  
    9. 2  
    10. your input is 2 !  
    11. 1  
    12. your input is 1 !  
    13. q  
    14. quit successful !  

     
    由于自己没有系统的看过shell语法的书,在这里只是简单的把shell的语法类比于C语言的来学习。通过这上面一个简单的例子,我主要归纳出啦下面3点得不同。
              1shell中函数的定义与函数的调用。
              在shell中,函数的定义不需要像在C语言中那样要指明函数的返回值类型,函数的参数个数以及每个参数的类型。
    写到这里大家首先会想到难道shell中的函数都没有返回值么?不是,shell中的函数可以有返回值的,下面我通过自己总结的两个方法来讲解:1echo法,2)全局变量法。
             1)echo
    在被调用函数中需要返回的值,使用echo将其显示至stdout,然后在调用的地方再使用`func var1`获得stdout中的值,获得值可以直接赋值给变量。例如:
    [plain] view plaincopy
    1. #!/bin/bash  
    2. #  echo法,返回一个字符串的长度  
    3. varCnt()  
    4. {  
    5.         var=$1  
    6.         ret=0  
    7.         if [ "$var" != "" ] ; then  
    8.                 ret=${#var}  
    9.         fi  
    10.         echo $ret  
    11.   
    12. }  
    13.   
    14. main()  
    15. {  
    16.         printf "varCnt's 's return value is %s "  `varCnt ""`  
    17.         printf "varCnt's 's return value is %s "  `varCnt "12345678"`  
    18.   
    19. }  
    20.   
    21. main  
    22.   
    23. exit  0  

    程序运行结果:
    [plain] view plaincopy
    1. root@james-desktop:/home/workspace/mycode# ./testecho.sh   
    2. varCntGlobeVar's 's return value is 0 varCntGlobeVar's 's return value is 8   

     
                 2)全局变量法
      这个比较简单,声明一个全局变量 declare -i g_ret ,在function的返回值存储在全局变量中。调用处在函数执行完后,使用就可以了。例如:
    [plain] view plaincopy
    1. #!/bin/bash  
    2.   
    3. #  全局变量法,返回一个字符串的长度  
    4. varCntGlobeVar()  
    5. {  
    6.         var=$1  
    7.         if [ "$var" != "" ] ; then  
    8.                 g_ret=${#var}  
    9.         fi  
    10. }  
    11.   
    12. main()  
    13. {  
    14.         declare -i g_ret=0  
    15.         varCntGlobeVar ""  
    16.         printf "varCntGlobeVar's 's return value is %d "  $g_ret  
    17.         varCntGlobeVar "12345678"  
    18.         printf "varCntGlobeVar's 's return value is %d "  $g_ret  
    19. }  
    20.   
    21. main  
    22. exit 0  

    程序运行结果:
    [plain] view plaincopy
    1. root@james-desktop:/home/workspace/mycode# ./testvar.sh   
    2. varCntGlobeVar's 's return value is 0 varCntGlobeVar's 's return value is 8  

     
    通过这两个脚本运行的结果来看,这两个方法都是可以的,目前只想到这两种方法,各位要是还有其他的办法可以告诉我一下。
         Shell中的函数的参数都可以在shell函数中通过$0,$1.......一些相关的特殊变量得到,而不需要跟C语言中的函数一样通过值传递的方式给函数传递参数。相应的shell中函数的掉用也不同,直接通过函数名就可以,函数后面的圆括号都不要,然后要是有参数的话就直接在函数名后面加空格,然后输入参数就可以,如果是多个参数的话,中间要用空格分开。
    还有一个比较重要的区别就是shell中的定义可以是在另一函数体内的,如上面的第一个例子中的那样。
              2shell中的与C语言中的条件判断不同。
    之前我一直以为在shell中与在C语言中条件判断的就是使用的符号不同,shell中是中括号,C语言中是圆括号。但是这个中括号不是简单的中括号,下面就有我来简单的说一下:
    这个左中括号(注意我说的是左中括号)"["LinuxUnix系统中的test命令的别名,test 及其别名通常都可以在 /usr/bin 或 /bin (取决于操作系统版本和供应商)中找到。
    当您使用左方括号而非 test ,其后必须始终跟着一个空格、要评估的条件、一个空格和右方括号。右方括号不是任何东西的别名,而是表示所需评估参数的结束。条件两边的空格是必需的,这表示要调用 test,以区别于同样经常使用方括号的字符/模式匹配操作。
    test 和 的语法如下:
    test expression
    [ expression ]
    在这两种情况下,test 都评估一个表达式,然后返回真或假。如果它和 ifwhile 或 until 命令结合使用,则您可以对程序流进行广泛的控制。不过,您无需将 test 命令与任何其它结构一起使用;您可以从命令行直接运行它来检查几乎任何东西的状态。
    因为它们彼此互为别名,所以使用 test 或 均需要一个表达式。表达式一般是文本、数字或文件和目录属性的比较,并且可以包含变量、常量和运算符。
               3shell中的switch/case语句与C语言中的区别。
    这么写大家肯定要说我,因为在shell中就没有switch/case语句。不过case命令可类比C语言的switch/case语句,esac表示case语句块的结束。C语言的case只能匹配整型或字符型常量表达式,而Shell脚本的case可以匹配字符串和Wildcard,每个匹配分支可以有若干条命令,末尾必须以;;结束,执行时找到第一个匹配的分支并执行相应的命令,然后直接跳到esac之后,不需要像C语言一样用break跳出。大家看到我的第一个例子就是通过break语句直接跳出while循环。
    好吧,先写到这里,以后想到啦再补充,如果有什么不足之处还请大家一定指出,一起学习一起提高哈。呵呵!加油!

    在shell中编程实现获取c函数输出

    http://blog.csdn.net/zhangmuyan/article/details/7568284


    最近碰到这样一个问题,通过c语言写了一个程序,然后再shell脚本中获取这个c语言的输出,执行其他的处理,该如何
    做?比如,c语言程序输出hello world,通过shell脚本获取到这个输出,然后输出:the first is hello, the second is world.该如何做?
    我把我的解决方案整理如下:
    1. 编程和编译c语言程序
       源代码如下hello.c:
       #include <stdio.h>
       int main()
       {
          printf("hello world");
          return 1;
       }
       编译程序 : gcc hello.c -o hello;生成了一个可执行文件hello,在Shell中执行hello程序,得到输出hello world
    2. 第二步编写脚本
       在shell环境中执行vi sh ,sh脚本的内容如下:
       MYPATH=/home/minrongf
       arg1=$(echo `/home/minrongf/hello` | awk '{print $1 }')
       arg2=$(echo `/home/minrongf/hello` | awk '{print $2 }')
       echo the first is $arg1, the second is $arg2
     
       然后给脚本sh赋与可执行的权限: chmod a+x sh
       然后执行这个脚本,将看到这个输出.
       Shell>./sh
       Shell>the first is hello, the second is world

       在编写脚本的时候,也可以把c语言的结果输入到一个临时文件中,然后处理这个临时文件.
       创建另外一个脚本sh2.脚本内容如下:
     
       MYTMPFILE=/opt/tmp/1.txt
       MYPATH=/home/minrongf
       $MYPATH/hello > $MYTMPFILE
       while read arg1 arg2
       do
          printf " the first is $arg1, the second is $arg2/n"
       done < $MYTMPFILE
       rm $MYTMPFILE

    如何在C语言中调用shell命令

    http://www.cnblogs.com/niocai/archive/2011/07/20/2111896.html


    1、system(执行shell 命令)
    相关函数 fork,execve,waitpid,popen
    表头文件 #include<stdlib.h>
    定义函数 int system(const char * string);
    函数说明 system()会调用fork()产生子进程,由子进程来调用/bin/sh-c
    string来执行参数string字符串所代表的命令,此命令执行完后随
    即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时
    搁置,SIGINT和SIGQUIT 信号则会被忽略。
    返回值 如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-
    1。若参数string为空指针(NULL),则返回非零值。如果system()调
    用成功则最后会返回执行shell命令后的返回值,但是此返回值也有
    可能为system()调用/bin/sh失败所返回的127,因此最好能再检查
    errno 来确认执行成功。
    附加说明 在编写具有SUID/SGID权限的程序时请勿使用system(),system()会
    继承环境变量,通过环境变量可能会造成系统安全的问题。
    范例:
    #include<stdlib.h>
    main()
    {
    system(“ls -al /etc/passwd /etc/shadow”);
    }



    2、popen(建立管道I/O)
    相关函数 pipe,mkfifo,pclose,fork,system,fopen
    表头文件 #include<stdio.h>
    定义函数 FILE * popen( const char * command,const char * type);
    函数说明 popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c
    来执行参数command的指令。参数type可使用“r”代表读取,“w”
    代表写入。依照此type值,popen()会建立管道连到子进程的标准输
    出设备或标准输入设备,然后返回一个文件指针。随后进程便可利
    用此文件指针来读取子进程的输出设备或是写入到子进程的标准输
    入设备中。此外,所有使用文件指针(FILE*)操作的函数也都可以使
    用,除了fclose()以外。
    返回值 若成功则返回文件指针,否则返回NULL,错误原因存于errno中。
    错误代码 EINVAL参数type不合法。
    注意事项 在编写具SUID/SGID权限的程序时请尽量避免使用popen(),popen()
    会继承环境变量,通过环境变量可能会造成系统安全的问题。
    范例:
    ?
    #include<stdio.h>
    main()
    {
    FILE * fp;
    char buffer[80];
    fp=popen(“cat /etc/passwd”,”r”);
    fgets(buffer,sizeof(buffer),fp);
    printf(“%s”,buffer);
    pclose(fp);
    }
    执行 root :x:0 0: root: /root: /bin/bash


    3、使用vfork()新建子进程,然后调用exec函数族
      
    复制代码
    #include<unistd.h>
    main()
    {
        char * argv[ ]={“ls”,”-al”,”/etc/passwd”,(char*) };
       
        if(vfork() = =0)
        {
            execv(“/bin/ls”,argv);
        }else{        
            printf(“This is the parent process\n”);
        }
    }
    复制代码