Monthly Archives: August 2011

Shell – Script Çalıştırma – Ortam Değişkenlerini Set Etmek


lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ set LD_LIBRARY_PATH = /opt/lib:$LD_LIBRARY_PATH
lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ echo $LD_LIBRARY_PATH

yaptım, ama olmadı, çünkü;

Shells and Shell Scripts yazısında açıklandığı üzere:

Running Scripts kısmında;

Bir Shell Script’ini çalıştırmak için üç farklı yol vardır:

Direct Execution: Bir Shell Script‘ini çalıştırabilmek için en basit yol, chmod ile text file‘ı executable yapmaktır. Bundan sonra, script, eğer current working directory‘de ise ya da shell‘in PATH‘inde tanımlı ise, adı yazılarak çalıştırılabilir.

Bir script çalıştırıldığında, yeni bir shell yaratır ve bu yeni shell‘de script içinde belirtilmiş olan her bir komutu sırayla çalıştırır. Script‘in sonuna gelindiğinde, yeni shell kapanır. Yeni shell’in script dolayısıyla sistemde yaptığı değişiklikler, shell sonlandığında kaybolur.

Shell Execution: Bir script’i yeni shell context’i içinde çalıştırmanın diğer yolu, shell’i script’i parametre olarak verip çalıştırmaktır. Bu aslında Direct Execution‘dur. Doğrudan, sh‘ı çalıştırarak, sh options değiştirilebilir.

csh -x change şeklinde çalştırıldığında, çalışan komutlar da output‘ta gösterilir.

source Execution: Bir script‘i mevcut shell’de çalıştırabilmek için, internal shell command olan source kullanılır. Çalıştırma, mevcut shell’in context‘inde olduğu için, script‘in shell’de yaptığı değişiklikler, shell sonlanıncaya kadar durur.

Burada, her shell‘in bir child process olduğu ve scope’u olduğu anlatılıyor. Benim karşılaştığım problem ise, aslında, tam olarak bununla ilgili değil ama, sistem geneli ortam değişkenleri scope‘u, environment scope – yani kısaca Environment ile ilgili.

Yukarıda yaptığım shell işlemlerinde, öncelikle bir terminal açmıştım. Terminal, bir shell başlattı. Bu yeni shell‘de yazmış olduğum, set komutu bir ortam değişkenini değiştirdi. Yeni bir terminal, yani shell açıp bu ortam değişkenini yazdırdığımda değerinin değişmediğini gördüm.

Export

A – Bourne Shell mark for export flag‘de belirtildiği gibi:

Bir değişkeni ortam – environment‘da bulundurabilmek için, o değişkeni explictly export etmek gerekir ki diğer programlar da onu bulabilsin.

Burada ayrıca,

Bunu yapmanın bir diğer yolu, set‘i -a option‘u ile birlikte kullanmaktır:
set -a
Bu yapıldığında, değiştirilen ya da yaratılan değişken export edilir.

Bu işlemlerin ve export‘un sebebi, UNIX – MAN Sayfaları ile Dosya Okuma-Arama Komutları ve Ortam Değişkenleri yazısında yazıyor.

Ayrıca, Environment Variables‘a bakılabilir.

Yukarıdaki anlatılanlardan anlaşılacağı gibi:

lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ set LD_LIBRARY_PATH = /opt/lib:$LD_LIBRARY_PATH
lifeinbeta@lifeinbeta:~$export LD_LIBRARY_PATH
lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ echo $LD_LIBRARY_PATH

yazmalıydım.

Yukarıdaki, shell‘de script çalıştırma yöntemlerinden ilkini kullandım. export ile ortam değişkenini değiştirdim. Ancak, açık olan shell, yani child process sonlanana kadar geçerli olacaktır. Bu yüzden her defasında bunu set etmek yerine,

Uygun login dosyası – GNU Bash Shell için .bash_profile kullanılarak her oturum için LD_LIBRARY_PATH otomatik olarak set edilebilir.

.bashrc‘de şunu yazdım:

export LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH

Bunun için;

lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ vim ~/.bashrc
lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ source ~/.bashrc
lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ printenv LD_LIBRARY_PATH
/opt/lib:

işlemlerini yaptım. En son,

.bashrc‘de şunlar yazılıydı:

lifeinbeta@lifeinbeta:~$ cat .bashrc
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
export PATH=$PATH:$JAVA_HOME/bin:~/play-1.1.1
export LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH
Advertisements

Leave a comment

Filed under Shell, UNIX

ar ve binutils


Binutils

Binutils paketindeki programların büyük çoğunluğu, BFD, yani Binary File Descriptor kütüphanesini kullanır. Bu kütüphane, alt-seviyede manipülasyonlar yapmayı sağlar. Yine, çoğu program opcodes kütüphanesini kullanır. Bu kütüphane, makine komutlarını assemble ve disassemble etmeyi sağlar.

Binutils paketindeki kütüphaneler:

lifeinbeta@lifeinbeta:/usr/lib/ldscripts$ locate libbfd
/usr/lib/libbfd-2.20.1-system.20100303.so
lifeinbeta@lifeinbeta:/usr/lib/ldscripts$ locate libopcodes
/usr/lib/libopcodes-2.20.1-system.20100303.so

ar

ar utility, binutils‘deki utility‘lerden biridir.
Binutils‘in içeriği için, Linux From Scratch – Contents of Binutils‘e bakılabilir.

ar, Arşiv Kütüphaneleri/Statik Kütüphaneler üzerinde oluşturma, değiştirme, içindekileri çıkarma(extract) işlemleri yapmak için kullanılır.

man ar  

Description:(Kısaltılmıştır) `ar`, `s` *modifier*'ı ile birlikte kullanıldığında,
oluşturulacak olan arşivde bulunacak olan *relocatable object module*'lerin içinde bulunan *symbol*'lere bir *index* tablosu oluşturur.

Bir Object File‘ın Symbol tablosu, bir programın sembolik tanımlamalarını ve referanslarını locate ve relocate etmek için gerekli olan bilgileri tutar.

Bu index tablosunu listelemek için nm -sya da nm --print-armap kullanılır. Eğer bir arşiv dosyasında bu tablo yoksa, sadece bu tabloyu eklemek için ar utility‘nin içindeki ranlib kullanılabilir.

Şimdi, ar ile ilgili anlattıklarımın uygulamasını yapalım.

Arşiv Dosyasının – Statik kütüphanenin oluşturulması

lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ ar -qcv libdummy.a countdown.o factorial.o
a - countdown.o  <- *Verbose* modda olduğumuz için,
a - factorial.o  <- yapılan işlem hakkında bilgiler veriliyor.
lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ ls  <- libdummy.a gerçekten oluştu mu, görelim.
countdown.c  factorial.c  factorial.o  main    main.o
countdown.o  factorial.h  libdummy.a   main.c

Arşivdeki Index Tablosunun Görülmesi

lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ nm -s libdummy.a

Archive index:  <- arşivdeki index table
countdown in countdown.o                  <- countdown.o'nun içinde countdown fonksiyonu var.
__i686.get_pc_thunk.bx in countdown.o     <- bu fonksiyonun ne yaptığını daha sonra açıklayacağım.[TODO]
countdown_by_adding in countdown.o        <- countdown.o'nun içinde countdown_by_adding fonksiyonu var.
countdown_with_modulo in countdown.o      <- countdown.o'nun içinde countdown_with_modulo fonksiyonu var.
fact in factorial.o                       <- factorial.o'nun içinde fact fonksiyonu var.
__i686.get_pc_thunk.bx in factorial.o     <- bu fonksiyonun ne yaptığını daha sonra açıklayacağım.[TODO]

countdown.o: <- Kütüphanedeki birinci parça, yani relocatable object module 1  <- aşağıda bu object modülündeki sembollere olan indexler gösteriliyor.
         U _GLOBAL_OFFSET_TABLE_    <- bir index entry ile GOT Tablosu belirtiliyor.
00000000 T __i686.get_pc_thunk.bx   <- bir index entry
00000000 T countdown                <- bir index entry ile countdown fonksiyonunu gösteren symbol belirtiliyor.
00000044 T countdown_by_adding      <- bir index entry ile countdown_by_adding fonksiyonunu gösteren symbol belirtiliyor.
0000008e T countdown_with_modulo    <- bir index entry ile countdown_with_modulo fonksiyonunu gösteren symbol belirtiliyor.
         U printf                   <- bir index entry ile printf fonksiyonunu gösteren symbol beliriliyor.

factorial.o: <- Kütüphanedeki ikinci parça, relocatable object module 2
         U _GLOBAL_OFFSET_TABLE_
00000000 T __i686.get_pc_thunk.bx
00000000 T fact

Yukarıda archive index table‘ı görüntüledik.

Index Table‘daki entry‘lerin object module‘ler içindeki symbol‘lere referans verdiğini söyledim. Peki, relocatable objecet file‘lardaki bu sembolleri görelim.

Relocatable Object Module/File‘lardaki Sembol Tablolarının Görülmesi

Bunun için objdump utility‘si, -t parametresi ile kullanılabilir.

lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ objdump -t libdummy.a
In archive libdummy.a:

countdown.o:     file format elf32-i386

SYMBOL TABLE:
00000000 l    df *ABS*  00000000 countdown.c
00000000 l    d  .text  00000000 .text
00000000 l    d  .data  00000000 .data
00000000 l    d  .bss   00000000 .bss
00000000 l    d  .rodata    00000000 .rodata
00000000 l    d  .text.__i686.get_pc_thunk.bx   00000000 .text.__i686.get_pc_thunk.bx
00000000 l    d  .note.GNU-stack    00000000 .note.GNU-stack
00000000 l    d  .comment   00000000 .comment
00000000 l    d  .group 00000000 .group
00000000 g     F .text  00000044 countdown     <- bir sembol
00000000 g     F .text.__i686.get_pc_thunk.bx   00000000 .hidden __i686.get_pc_thunk.bx  <- bir sembol
00000000         *UND*  00000000 _GLOBAL_OFFSET_TABLE_  <- UND a dikkat!
00000000         *UND*  00000000 printf                 <- UND a dikkat!
00000044 g     F .text  0000004a countdown_by_adding  <- diğer bir sembol
0000008e g     F .text  00000054 countdown_with_modulo <- diğer bir sembol

factorial.o:     file format elf32-i386

SYMBOL TABLE:
00000000 l    df *ABS*  00000000 factorial.c
00000000 l    d  .text  00000000 .text
00000000 l    d  .data  00000000 .data
00000000 l    d  .bss   00000000 .bss
00000000 l    d  .text.__i686.get_pc_thunk.bx   00000000 .text.__i686.get_pc_thunk.bx
00000000 l    d  .note.GNU-stack    00000000 .note.GNU-stack
00000000 l    d  .comment   00000000 .comment
00000000 l    d  .group 00000000 .group
00000000 g     F .text  00000035 fact  <- bir sembol
00000000 g     F .text.__i686.get_pc_thunk.bx   00000000 .hidden __i686.get_pc_thunk.bx  <- diğer bir sembol
00000000         *UND*  00000000 _GLOBAL_OFFSET_TABLE   <- UND'a dikkat!

Görüldüğü gibi, her relocatable object module‘ün bir sembol tablosu var.

Arşiv başlıklarının Görülmesi

Ayrıca, binutils‘deki diğer bir utility olan objdump‘ı -a parametresi ile kullanarak arşiv dosyasındaki relocatable object module‘lerin adları ve formatlarını görebiliriz.

lifeinbeta@lifeinbeta:~/CSWORKS/C/soexample$ objdump -a libdummy.a
In archive libdummy.a:

countdown.o:     file format elf32-i386
rw-r--r-- 1000/1000   1460 Jun  5 00:04 2011 countdown.o

factorial.o:     file format elf32-i386
rw-r--r-- 1000/1000   1028 Jun  5 00:04 2011 factorial.o

Yukarıdaki, -a parametresi, --archive-headers, Displays archive header information anlamındadır.

ar utility‘sinin açıklamasına devam edelim…

Aşağıda, Synopsis‘i kısaltarak yazdım.

SYNOPSIS: ar [-]p[mod] archive member...

Buradaki parametreler:

p: çalıştırılacak olan işlemi belirtir. Burada, bunun için q‘yu kullandım.

mod: Yapılacak olan işlem hakkındaki detaylar belirtilir. Burada, bunun için c ve v‘yi kullandık.

-c: Create, aşiv dosyasını oluşturur.

-v: Verbose, işlem yapılırken verbose modunda yapılmasını ister. Yani, yapılan işlemler hakkında özet bilgi gösterilir.

-q: Quick Append, beliritilen member‘ları yani dosyaları, arşive ekle demek içindir.

Leave a comment

Filed under C, disassembling, gcc