Skip to content

Instantly share code, notes, and snippets.

@kikitux
Forked from sshaw/bash_builtins.md
Created June 30, 2018 20:28
Missing manual of internal Bash functions, useful when writing loadable builtins

Internal Bash functions, useful when writing loadable builtins

Find an environment variable

SHELL_VAR* find_variable(const char* name)

Example

SHELL_VAR *var = find_variable("FOO");
if(!var)
  printf("FOO not set\n");

Set an environment variable to a string value

SHELL_VAR* bind_variable(const char* name, char* value, int flags)

Example

SHELL_VAR *var = bind_variable("FOO", "fooval", 0);

Set an environment variable to a string value if it's not already set

SHELL_VAR* set_if_not(char *name, char *value)

Check if an environment variable is set

var_isset(SHELL_VAR* var)

This is a macro

Example

if(var_isset(var) == 0)
  printf("Not set\n");

Check if an environment variable is an array

array_p(SHELL_VAR* var)

This is a macro

Example

if(array_p(var) == 0)
  printf("Not an array\n");

Get an environment variable that's an array

GET_ARRAY_FROM_VAR(char* name, SHELL_VAR *var, ARRAY *arr)

Unset an environment variable

int unbind_variable(const char* name)

Example

if(unbind_variable("FOO") == -1)
  printf("FOO was not set");

Get a variable's value

char* get_variable_value(SHELL_VAR *var)

Example

SHELL_VAR *var = bind_variable("FOO", "sshaw", 0);
printf("FOO: %s\n", get_variable_value(var));

Create an array

SHELL_VAR* make_new_array_variable(const char* name)
ARRAY* array_cell(SHELL_VAR *var)

array_cell is a macro. Most (all?) array operations are done on the value returned by array_cell.

Example

SHELL_VAR *var = make_new_array_variable("AN_ARRAY")
if(array_p(var) == 0) {
  printf("Array creation failed\n");
  return;
}

ARRAY *arr = array_cell(var);

Unshift a value on to an array

array_push(ARRAY *arr, char *val)

Yes, this does an unshift

Popping an array

array_pop(ARRAY *arr)

Inserting a value into an array

int array_insert(ARRAY *arr, arrayind_t pos, char *val);

Here arrayind_t is an intmax_t, which is more or less an int.

Example

SHELL_VAR *var = make_new_array_variable("AN_ARRAY")
/* Error checking */
ARRAY *arr = array_cell(var);
if(array_insert(arr, 0, "Cero") < 0)
  printf("Insert failed\n");

Get the number of elements in an array

int array_num_elements(ARRAY *arr)

This is a macro

Example

SHELL_VAR *var = make_new_array_variable("AN_ARRAY")
/* Error checking */
ARRAY *arr = array_cell(var);
printf("Elements: %d\n", array_num_elements(arr));

Print an environment variable's value

void print_var_value(SHELL_VAR *var, int quote)

If quote is non-zero and var contains meta chars value will be quoted. No trailing newline is added.

Example

print_var_value(var, 0);
print_var_value(var_with_meta_chars, 1);

Print an environment variable's name and value

void print_assignment(SHELL_VAR *var)

Prints in export format, i.e. VAR=VALUE

$0, $1, ... $9

char *dollar_vars[]

Example

for(int i = 0; i < 10; i++)
  if(dollar_vars[i])
    printf("$%d: %s\n", i, dollar_vars[i]);

$$

pid_t dollar_dollar_pid

Process id of the bash process your builtin was loaded into.

Example

extern pid_t dollar_dollar_pid;
printf("$$: %d\n", dollar_dollar_pid);

Name of the currently running builtin

char* this_command_name

Example

extern char* this_command_name;
printf("Name: %s\n", this_command_name);

Author

Skye Shaw http://github.com/sshaw

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment