J4GGo

        Collection of Pearls:

        awk -v awkarg=$2 '{ print awkarg }' $1

        echo 'one two three' | tr \  '\n'

        FILENAME==ARGV[1] { one[FNR]=$1 }
        FILENAME==ARGV[2] { two[FNR]=$1 }
        END { for (i=1; i<=length(one); i++) print one[i], two[i] }

## BACKUP - RESTORE

Should work out of box. Add missing files if necessary..

  time      uoB*
  tree      uoB
  ed
  ihave     uoB  (A-B, A&B, A+B, B-A)
  snake.c

* uoB -- useless to do outside of Bellard's jsLinux:

Check kernel version

  # uname -r
  4.12.0-rc6-g48ec1f0-dirty

Check kernel version and what is built into binary

  # busybox
  24 March 2016 -- BusyBox 1.24.2 (stable)

  Currently defined functions:

  [, [[, addgroup, ..

Why results doen't match?

  find / -perm /u=x -type l -exec ls -l {} \; 2>&1 | grep busybox | wc -l
  227
  busybox | perl -pe 's/[^,]//g' | perl -pe 's/,/,\n/g' | wc -l
  240

which 13?

Commands we must have..

  1  man
  1  echo,
  D  pwd, cd, mkdir, ls, ln, cp, mv, rm, touch, cmp, diff, patch, find,
  3  chown, chgrp, chmod,
  3  tar, bzip2, gzip,
  4  fdisk, dd, df, du,
  1  tree,
  1  ed,
  C  grep, cat, wc, less, head, tail, tr, sed, awk, sort, uniq, paste
  1  passwd,
  5  ps, kill, jobs, fg, bg,
  2  dmesg, uname,
  2  gcc, make
  ---
  50

Missing programs have to be installed..

  tree    http://mama.indstate.edu/users/ice/tree/
  ed      https://www.gnu.org/software/ed/
  tr      http://heirloom.sourceforge.net/tools.html
  paste   google: David M. Ihnat and David MacKenzie paste.c
          https://git.busybox.net/busybox/tree/coreutils/paste.c

  bzip2 7z zip unzip rar unrar

Other commands (not very useful in jsLinux)

  mkfs, mkswap, fsck,
  mount, umount,
  crontab, su, sudo
  nano,
  ping, traceroute, ip, nslookup, dig, nmap,
  apt, dpkg

template to build paste-like script in awk

https://www.wlsdevelop.com/index.php/en
/blog?option=com_content&view=article&id=60

  # cat awkpaste.awk
  FILENAME==ARGV[1] { one[FNR]=$1 }
  FILENAME==ARGV[2] { two[FNR]=$1 }

  END {
      for (i=1; i<=length(one); i++) {
          print one[i], two[i]
      }
  }

  # cat one
  me alone
  and you alone

  # cat two
  come together
  right now

  # awk -f awe.awk one two
  me come
  and right

Another approach

  #!/bin/bash

  awk '
    BEGIN {
            # load array with contens f1.txt
            while ( getline < "f1.txt" > 0 )
              {
                f1_counter++
                f1[f1_counter] = $1
              }
    }
    {
      print $1, $2, f1[NR], $3
    } ' f2.txt

  EOF

How to use bash script arguments inside awk source.

  awk -v awkarg=$2 '{ print awkarg }' $1

About ldd

  https://www.lifewire.com/find-shared-libraries-ldd-command-4017941

  $ldd -v /path/to/program/executable

where -v stands for "verbose"


# SESSION: TOUCH - BUILD - BACKUP - ROLLBACK MACHINE - RESTORE

1. login, check your current folder, create time mark (started at)

  # cd
  # touch touched

2. Build your lab. Let's say changes were made only in
   /root /usr /etc folders: then create a backup.

ATTENTION! bup.tgz have to be removed before tar (jsLinux bug)

  # cd /
  # rm -f bup.tgz
  # tar cv `find /etc /root /usr -newer touched` | gzip > bup.tgz
  # export_file bup.tgz

3. Reboot from untouched (clean) HD image

4. Restore files

  [ paste ] bup.tgz
  ls -1 /root
  ..
  bup.tgz
  ..
  cd /
  cat bup.tgz | gzip -d | tar xf -
  check now - everything should work as before..


## ANNEX A. SIMPLE SNAKE GAME

<file snake.c>

  /*
    Found here:

          https://gist.github.com/petrvolny/5506059
     w
    a d   a - left  w - up  d - right  s - down
     s
    Build with:

      gcc snake.c -o snake -lncurses
   */

  #include <stdlib.h>
  #include <time.h>
  #include <string.h>
  #include <unistd.h>
  #include <math.h>
  #include <curses.h>

  #define SNAKE_MAX_LENGTH 12
  #define WIN_MSG "You are the WINNER!"
  #define WELCOME_MSG "We present you the ultimate SNAKE game!!!"
  #define LOST_MSG "Loooooser :-))))"
  #define UP 1
  #define DOWN 2
  #define LEFT 3
  #define RIGHT 4
  #define SNAKE_CHAR 'O'
  #define FOOD_CHAR 'F'
  #define WALL_CHAR '#'

  typedef struct SnakePart_ {
      int x;
      int y;
  } SnakePart;

  typedef struct Food_ {
      int x;
      int y;
  } Food;

  Food food;
  int direction;
  SnakePart snake[SNAKE_MAX_LENGTH];
  int snakeLength = 1;
  int row, col;

  void checkGame(void);

  // Initialization of ncurses and the game
  void initGame(void) {
      srand(time(NULL));
      for (int i=0; i<SNAKE_MAX_LENGTH; i++) {
          snake[i].x = -1;
          snake[i].y = -1;
      }

      initscr();
    if(has_colors() == FALSE)
    {	endwin();
      printf("Your terminal does not support color\n");
      exit(1);
    }

      getmaxyx(stdscr, row, col);
      noecho();
      cbreak();
      curs_set(0);
    start_color(); /* Start color */
    init_pair(1, COLOR_RED, COLOR_BLACK);
      attron(A_BOLD);
      clear();
      color_set(1, NULL);
  }

  // Randomly add fodd spot to the level
  void addFood() {
      int x,y;
      y = rand()%row;
      x = rand()%col;
      while ((mvinch(y, x) & A_CHARTEXT) != ' ') {
          y = rand()%row;
          x = rand()%col;
      }
      food.y = y;
      food.x = x;
  }

  // Draw food on a game plan
  void drawFood() {
      move(food.y, food.x);
      addch(FOOD_CHAR);
  }

  void initSnake() {
      snake[1].x = 2;
      snake[1].y = row/2;
      snake[0].x = 3;
      snake[0].y = row/2;
      snakeLength = 2;
      direction = RIGHT;
  }

  // Draw the the actual position of the snake
  void drawSnake() {
      int i=0;
      while (snake[i].x != -1 && snake[i].y != -1) {
          move(snake[i].y, snake[i].x);
          addch(SNAKE_CHAR);
          i++;
      }
  }

  // Helper method for shifting snake parts
  void shiftSnake() {
      int i=0;
      for (int i=snakeLength-1; i>=0; i--) {
          snake[i+1] = snake[i];
      }
  }

  // Helper method for the snake movement that moves snake head in a desired direction
  void addHead() {
       SnakePart origHead = snake[0];
       shiftSnake();
       switch (direction) {
          case UP:
              origHead.y--;
              break;
          case DOWN:
              origHead.y++;
              break;
          case LEFT:
              origHead.x--;
              break;
          case RIGHT:
              origHead.x++;
              break;
      }
      snake[0] = origHead;
  }

  // Helper method for snake movement that cuts the end of the snake
  void removeTail() {
      mvaddch(snake[snakeLength].y, snake[snakeLength].x, ' ');
      snake[snakeLength].x = -1;
      snake[snakeLength].y = -1;
  }

  // Refresh snake movement
  void moveSnake() {
      addHead();
      checkGame();
      mvaddch(snake[0].y, snake[0].x, SNAKE_CHAR);
      if (snake[0].x == food.x && snake[0].y == food.y) {
          snakeLength++;
          addFood();
      } else {
          removeTail();
      }
  }

  // Recognize snake control
  void setDirection(char c) {
      switch(c) {
          case 'w':
              direction = UP;
              break;
          case 's':
              direction = DOWN;
              break;
          case 'd':
              direction = RIGHT;
              break;
          case 'a':
              direction = LEFT;
              break;
      }
  }

  // Draw the winner screen
  void showWinner() {
      clear();
      mvprintw(row/2, col/2-strlen(WIN_MSG)/2, WIN_MSG);
      refresh();
  }

  // Draw the welcome screen
  void showWelcome() {
      clear();
      mvprintw(row/2, col/2-strlen(WELCOME_MSG)/2, WELCOME_MSG);
      refresh();
  }

  // Draw the welcome screen
  void showYouLoose() {
      clear();
      mvprintw(row/2, col/2-strlen(LOST_MSG)/2, LOST_MSG);
      refresh();
  }

  // Draw the level walls
  void drawLevel() {
      for (int i=0; i<row; i++) {
          mvaddch(i, 0, WALL_CHAR);
          mvaddch(i, col-1, WALL_CHAR);
      }
      for (int i=1; i<col-1; i++) {
          mvaddch(0, i, WALL_CHAR);
          mvaddch(row-1, i, WALL_CHAR);
      }
      for (int i=25; i<55; i++) {
          mvaddch(row/4, i, WALL_CHAR);
          mvaddch((row/4)*3, i, WALL_CHAR);
      }
  }

  // Check on a game state. Checked after every game step (see main())
  void checkGame() {
      if (snakeLength == SNAKE_MAX_LENGTH-1) {
          showWinner();
          timeout(-1);
          getch();
          endwin();
          exit(0);
      }
      if ((mvinch(snake[0].y, snake[0].x) & A_CHARTEXT) == WALL_CHAR) {
          showYouLoose();
          timeout(-1);
          getch();
          endwin();
          exit(0);
      }
  }

  // Game init function
  int main() {
      char c;

      initGame();
      showWelcome();
      getch();
      clear();
      initSnake();
      drawLevel();
      drawSnake();
      addFood();
      refresh();

      // Main game loop
      while (1) {
          timeout(70);
          c = getch();
          setDirection(c);
          clear();
          drawLevel();
          moveSnake();
          checkGame();
          drawSnake();
          drawFood();
          refresh();
      }
  }

EOF
