Setelah executable dihasilkan oleh linker, tugas berikutnya adalah menjalankannya dengan benar. Cara kita menjalankan executable menentukan apakah program menerima argumen, ke mana keluaran ditujukan, dan kode apa yang dikembalikan ke sistem operasi. Pada Chapter ini kita akan mempelajari cara menjalankan executable C di Linux, mengakses argumen command line, memeriksa exit code, serta memisahkan standard output dan standard error.
Menjalankan Executable Dasar #
Cara paling sederhana menjalankan executable di Linux adalah dengan memanggil nama file-nya beserta prefiks ./ bila berada di direktori kerja saat ini:
#include <stdio.h>
int main(void) {
printf("Halo dari program C.\n");
return 0;
}Simpan sebagai halo.c, kompilasi, lalu jalankan:
gcc -std=c11 -Wall -Wextra -o halo halo.c
./halo
echo $?Output yang Dihasilkan:
Halo dari program C.
0Mari kita telaah baris-baris perintah di atas:
./halo: shell menjalankan executablehalodi direktori saat ini; prefiks./diperlukan karena Linux tidak mencari executable di direktori kerja saat ini secara default.echo $?: variabel khusus$?menyimpan exit code dari perintah terakhir; nilai0berarti program berakhir sukses.
Argumen Command Line #
Banyak program C menerima argumen command line. Untuk mengakses argumen ini, fungsi main harus dideklarasikan dengan dua parameter: int argc (jumlah argumen) dan char *argv[] (array string argumen).
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Jumlah argumen : %d\n", argc);
for (int i = 0; i < argc; i++) {
printf(" argv[%d] = %s\n", i, argv[i]);
}
return 0;
}Jalankan tanpa argumen tambahan:
./argsOutput yang Dihasilkan:
Jumlah argumen : 1
argv[0] = ./argsJalankan dengan beberapa argumen:
./args --nama Budi --umur 17Output yang Dihasilkan:
Jumlah argumen : 5
argv[0] = ./args
argv[1] = --nama
argv[2] = Budi
argv[3] = --umur
argv[4] = 17Mari kita telaah baris-baris kode di atas:
- Baris 3 (
int main(int argc, char *argv[])): tanda tanganmainyang menerima argumen command line;argcmenyimpan jumlah argumen,argvadalah array pointer ke string argumen. - Baris 5 (
printf("Jumlah argumen : %d\n", argc);): mencetak jumlah argumen; argumen selalu minimal1karenaargv[0]berisi nama program itu sendiri. - Baris 6 (
for (int i = 0; i < argc; i++)): loop dari0hinggaargc - 1, mencetak setiap argumen. - Baris 7 (
argv[i]): setiap elemenargvadalah string C (arraychardiakhiri null);%smencetaknya.
Exit Code sebagai Sinyal Status #
Fungsi main mengembalikan nilai int ke sistem operasi. Nilai ini disebut exit code atau exit status. Konvensi POSIX menyatakan 0 berarti sukses, sementara nilai 1 sampai 255 menandakan berbagai jenis kegagalan.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("Pesan ke stdout\n");
fprintf(stderr, "Pesan ke stderr\n");
return 42;
}Kompilasi lalu jalankan, periksa exit code segera setelah program selesai:
gcc -std=c11 -Wall -Wextra -o keluaran keluaran.c
./keluaran
echo "exit code: $?"Output yang Dihasilkan:
Pesan ke stdout
Pesan ke stderr
exit code: 42Mari kita telaah baris-baris kode di atas:
- Baris 6 (
printf("Pesan ke stdout\n");): menulis ke standard output (file descriptor 1), yang biasanya terhubung ke terminal. - Baris 7 (
fprintf(stderr, "Pesan ke stderr\n");): menulis ke standard error (file descriptor 2), juga terhubung ke terminal secara default namun merupakan aliran terpisah dari stdout. - Baris 8 (
return 42;): mengembalikan42ke sistem operasi; nilai ini bisa diperiksa lewat variabel$?di shell.
Perlu diingat bahwa nilai exit code yang valid hanya 0 sampai 255. Bila program mengembalikan nilai di luar rentang tersebut (misalnya -1 atau 256), shell akan melakukan modulo 256 dan nilai yang terlihat bisa berbeda dari yang dikembalikan program.
Memisahkan stdout dan stderr #
Standard output dan standard error adalah dua aliran terpisah. Saat menjalankan program, keduanya biasanya tampil di terminal secara tercampur. Kita bisa memisahkannya dengan redirection shell:
./keluaran > stdout.txt 2> stderr.txt
echo "stdout.txt:"
cat stdout.txt
echo "stderr.txt:"
cat stderr.txtOutput yang Dihasilkan:
stdout.txt:
Pesan ke stdout
stderr.txt:
Pesan ke stderrOperator > mengarahkan stdout ke file, sementara 2> mengarahkan stderr (file descriptor 2) ke file lain. Pemisahan ini sangat berguna saat kita ingin menyimpan output normal ke satu file dan pesan kesalahan ke file lain untuk analisis terpisah.
Menjalankan di Background dan dengan Pipe #
Untuk program yang berjalan lama, kita bisa menjalankannya di background dengan akhiran &:
./program_lama &Shell langsung mengembalikan kontrol ke kita sambil menjalankan program secara paralel. Perintah jobs menampilkan daftar background job, dan wait menunggu semua background job selesai.
Untuk mengirimkan output satu program sebagai input program lain, gunakan pipe |:
./program_a | ./program_bProgram program_a berjalan sebagai penghasil output, dan program_b berjalan sebagai pembaca input. Kedua program berjalan secara konkuren, dengan output program_a mengalir ke input program_b.