home.social

#shellscripting — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #shellscripting, aggregated by home.social.

fetched live
  1. MIMEcroft.sh: a 3D game written in bash

    gmatht.github.io/j.cmd/www/MIM is a parody of every 3D game ever, that lovingly pokes fun of bash's reputation for poor performance - by subverting it. MIMEcroft.sh is written entirely in Bash. The game logic, GPU shaders, even the sounds and textures are procedurally generated with bash commands.

    One may wonder how MIMEcroft.sh pumps out 90fps at 4K given bash's reputation for poor performance. Indeed, the official GNU bash reference interpreter is poorly optimised compared to languages more commonly used for game development like C++. However, if your web-browser has a GUI it almost certainly also has a highly optimised JavaScript interpreter.

    The online JavaScript Commandline OS (j.cmd) did not port the reference implementation of bash and coreutils. Instead it takes the abstract language they describe. This language is translated into JavaScript, which a modern runtime can often reduce to machine code, resulting in performance over a thousand times faster than the original bash.

    For a concrete if somewhat contrived example say you are interested in finding numbers with 1337 squares, and use the one-liner:

    for i in `seq 1 10000`;do if echo $((i*i)) | grep 1337 > /dev/null;then echo $i;fi;done

    In the official bash interpreter, this may take a minute. However, j.cmd implements it by first transpiling it into:

    for (let i = 1; i <= 10000; i++) {
    if (String(i * i).includes("1337")) {
    process.stdout.write(i + "\n");
    }
    }
    sh2.lastExit = 0;

    Then it is all over in the blink of an eye.

    One might well argue that this is not a real bash game since it has to transpile to JS before being run. A stronger argument could be made that C++ games are not real C++ games. A C++ game also has to be compiled. In most "C++" games the developer doesn't even give you the C++ source, you only ever get the compiled machine code. MIMEcroft.sh is stored and distributed as bash. You can edit it as bash (try e.g. `vi /bin/mimecroft.sh` in j.cmd, changing `cys=0.900` to `cys=3.900` and playing the game again). The current version of j.cmd doesn't even cache the transpiled JS version of the game.
    ____________
    It is important to note that j.cmd is experimental and still has many bugs. One little way it is more robust than the traditional bash implementations is that traditional shells tend to break if they source a file that isn’t in their own special format. On the other hand, j.cmd sees different shell formats as just different ways of saying the same thing. It will quite happily run:

    for f in /home/examples/source.{bat,c,fish,sh,zsh}; do . $f; done

    Sourcing C files is still a work in progress in j.cmd. I recently added support for passing linked lists and pointers to bash variables/functions into sourced C functions, and cd'ing around C pointer structure.
    #bash #sh #shellScripting #Linux #games #3D #Javascript #GLSL

  2. MIMEcroft.sh: a 3D game written in bash

    gmatht.github.io/j.cmd/www/MIM is a parody of every 3D game ever, that lovingly pokes fun of bash's reputation for poor performance - by subverting it. MIMEcroft.sh is written entirely in Bash. The game logic, GPU shaders, even the sounds and textures are procedurally generated with bash commands.

    One may wonder how MIMEcroft.sh pumps out 90fps at 4K given bash's reputation for poor performance. Indeed, the official GNU bash reference interpreter is poorly optimised compared to languages more commonly used for game development like C++. However, if your web-browser has a GUI it almost certainly also has a highly optimised JavaScript interpreter.

    The online JavaScript Commandline OS (j.cmd) did not port the reference implementation of bash and coreutils. Instead it takes the abstract language they describe. This language is translated into JavaScript, which a modern runtime can often reduce to machine code, resulting in performance over a thousand times faster than the original bash.

    For a concrete if somewhat contrived example say you are interested in finding numbers with 1337 squares, and use the one-liner:

    for i in `seq 1 10000`;do if echo $((i*i)) | grep 1337 > /dev/null;then echo $i;fi;done

    In the official bash interpreter, this may take a minute. However, j.cmd implements it by first transpiling it into:

    for (let i = 1; i <= 10000; i++) {
    if (String(i * i).includes("1337")) {
    process.stdout.write(i + "\n");
    }
    }
    sh2.lastExit = 0;

    Then it is all over in the blink of an eye.

    One might well argue that this is not a real bash game since it has to transpile to JS before being run. A stronger argument could be made that C++ games are not real C++ games. A C++ game also has to be compiled. In most "C++" games the developer doesn't even give you the C++ source, you only ever get the compiled machine code. MIMEcroft.sh is stored and distributed as bash. You can edit it as bash (try e.g. `vi /bin/mimecroft.sh` in j.cmd, changing `cys=0.900` to `cys=3.900` and playing the game again). The current version of j.cmd doesn't even cache the transpiled JS version of the game.
    ____________
    It is important to note that j.cmd is experimental and still has many bugs. One little way it is more robust than the traditional bash implementations is that traditional shells tend to break if they source a file that isn’t in their own special format. On the other hand, j.cmd sees different shell formats as just different ways of saying the same thing. It will quite happily run:

    for f in /home/examples/source.{bat,c,fish,sh,zsh}; do . $f; done

    Sourcing C files is still a work in progress in j.cmd. I recently added support for passing linked lists and pointers to bash variables/functions into sourced C functions, and cd'ing around C pointer structure.
    #bash #sh #shellScripting #Linux #games #3D #Javascript #GLSL

  3. MIMEcroft.sh: a 3D game written in bash

    gmatht.github.io/j.cmd/www/MIM is a parody of every 3D game ever, that lovingly pokes fun of bash's reputation for poor performance - by subverting it. MIMEcroft.sh is written entirely in Bash. The game logic, GPU shaders, even the sounds and textures are procedurally generated with bash commands.

    One may wonder how MIMEcroft.sh pumps out 90fps at 4K given bash's reputation for poor performance. Indeed, the official GNU bash reference interpreter is poorly optimised compared to languages more commonly used for game development like C++. However, if your web-browser has a GUI it almost certainly also has a highly optimised JavaScript interpreter.

    The online JavaScript Commandline OS (j.cmd) did not port the reference implementation of bash and coreutils. Instead it takes the abstract language they describe. This language is translated into JavaScript, which a modern runtime can often reduce to machine code, resulting in performance over a thousand times faster than the original bash.

    For a concrete if somewhat contrived example say you are interested in finding numbers with 1337 squares, and use the one-liner:

    for i in `seq 1 10000`;do if echo $((i*i)) | grep 1337 > /dev/null;then echo $i;fi;done

    In the official bash interpreter, this may take a minute. However, j.cmd implements it by first transpiling it into:

    for (let i = 1; i <= 10000; i++) {
    if (String(i * i).includes("1337")) {
    process.stdout.write(i + "\n");
    }
    }
    sh2.lastExit = 0;

    Then it is all over in the blink of an eye.

    One might well argue that this is not a real bash game since it has to transpile to JS before being run. A stronger argument could be made that C++ games are not real C++ games. A C++ game also has to be compiled. In most "C++" games the developer doesn't even give you the C++ source, you only ever get the compiled machine code. MIMEcroft.sh is stored and distributed as bash. You can edit it as bash (try e.g. `vi /bin/mimecroft.sh` in j.cmd, changing `cys=0.900` to `cys=3.900` and playing the game again). The current version of j.cmd doesn't even cache the transpiled JS version of the game.
    ____________
    It is important to note that j.cmd is experimental and still has many bugs. One little way it is more robust than the traditional bash implementations is that traditional shells tend to break if they source a file that isn’t in their own special format. On the other hand, j.cmd sees different shell formats as just different ways of saying the same thing. It will quite happily run:

    for f in /home/examples/source.{bat,c,fish,sh,zsh}; do . $f; done

    Sourcing C files is still a work in progress in j.cmd. I recently added support for passing linked lists and pointers to bash variables/functions into sourced C functions, and cd'ing around C pointer structure.
    #bash #sh #shellScripting #Linux #games #3D #Javascript #GLSL

  4. MIMEcroft.sh: a 3D game written in bash

    gmatht.github.io/j.cmd/www/MIM is a parody of every 3D game ever, that lovingly pokes fun of bash's reputation for poor performance - by subverting it. MIMEcroft.sh is written entirely in Bash. The game logic, GPU shaders, even the sounds and textures are procedurally generated with bash commands.

    One may wonder how MIMEcroft.sh pumps out 90fps at 4K given bash's reputation for poor performance. Indeed, the official GNU bash reference interpreter is poorly optimised compared to languages more commonly used for game development like C++. However, if your web-browser has a GUI it almost certainly also has a highly optimised JavaScript interpreter.

    The online JavaScript Commandline OS (j.cmd) did not port the reference implementation of bash and coreutils. Instead it takes the abstract language they describe. This language is translated into JavaScript, which a modern runtime can often reduce to machine code, resulting in performance over a thousand times faster than the original bash.

    For a concrete if somewhat contrived example say you are interested in finding numbers with 1337 squares, and use the one-liner:

    for i in `seq 1 10000`;do if echo $((i*i)) | grep 1337 > /dev/null;then echo $i;fi;done

    In the official bash interpreter, this may take a minute. However, j.cmd implements it by first transpiling it into:

    for (let i = 1; i <= 10000; i++) {
    if (String(i * i).includes("1337")) {
    process.stdout.write(i + "\n");
    }
    }
    sh2.lastExit = 0;

    Then it is all over in the blink of an eye.

    One might well argue that this is not a real bash game since it has to transpile to JS before being run. A stronger argument could be made that C++ games are not real C++ games. A C++ game also has to be compiled. In most "C++" games the developer doesn't even give you the C++ source, you only ever get the compiled machine code. MIMEcroft.sh is stored and distributed as bash. You can edit it as bash (try e.g. `vi /bin/mimecroft.sh` in j.cmd, changing `cys=0.900` to `cys=3.900` and playing the game again). The current version of j.cmd doesn't even cache the transpiled JS version of the game.
    ____________
    It is important to note that j.cmd is experimental and still has many bugs. One little way it is more robust than the traditional bash implementations is that traditional shells tend to break if they source a file that isn’t in their own special format. On the other hand, j.cmd sees different shell formats as just different ways of saying the same thing. It will quite happily run:

    for f in /home/examples/source.{bat,c,fish,sh,zsh}; do . $f; done

    Sourcing C files is still a work in progress in j.cmd. I recently added support for passing linked lists and pointers to bash variables/functions into sourced C functions, and cd'ing around C pointer structure.
    #bash #sh #shellScripting #Linux #games #3D #Javascript #GLSL

  5. MIMEcroft.sh: a 3D game written in bash

    gmatht.github.io/j.cmd/www/MIM is a parody of every 3D game ever, that lovingly pokes fun of bash's reputation for poor performance - by subverting it. MIMEcroft.sh is written entirely in Bash. The game logic, GPU shaders, even the sounds and textures are procedurally generated with bash commands.

    One may wonder how MIMEcroft.sh pumps out 90fps at 4K given bash's reputation for poor performance. Indeed, the official GNU bash reference interpreter is poorly optimised compared to languages more commonly used for game development like C++. However, if your web-browser has a GUI it almost certainly also has a highly optimised JavaScript interpreter.

    The online JavaScript Commandline OS (j.cmd) did not port the reference implementation of bash and coreutils. Instead it takes the abstract language they describe. This language is translated into JavaScript, which a modern runtime can often reduce to machine code, resulting in performance over a thousand times faster than the original bash.

    For a concrete if somewhat contrived example say you are interested in finding numbers with 1337 squares, and use the one-liner:

    for i in `seq 1 10000`;do if echo $((i*i)) | grep 1337 > /dev/null;then echo $i;fi;done

    In the official bash interpreter, this may take a minute. However, j.cmd implements it by first transpiling it into:

    for (let i = 1; i <= 10000; i++) {
    if (String(i * i).includes("1337")) {
    process.stdout.write(i + "\n");
    }
    }
    sh2.lastExit = 0;

    Then it is all over in the blink of an eye.

    One might well argue that this is not a real bash game since it has to transpile to JS before being run. A stronger argument could be made that C++ games are not real C++ games. A C++ game also has to be compiled. In most "C++" games the developer doesn't even give you the C++ source, you only ever get the compiled machine code. MIMEcroft.sh is stored and distributed as bash. You can edit it as bash (try e.g. `vi /bin/mimecroft.sh` in j.cmd, changing `cys=0.900` to `cys=3.900` and playing the game again). The current version of j.cmd doesn't even cache the transpiled JS version of the game.
    ____________
    It is important to note that j.cmd is experimental and still has many bugs. One little way it is more robust than the traditional bash implementations is that traditional shells tend to break if they source a file that isn’t in their own special format. On the other hand, j.cmd sees different shell formats as just different ways of saying the same thing. It will quite happily run:

    for f in /home/examples/source.{bat,c,fish,sh,zsh}; do . $f; done

    Sourcing C files is still a work in progress in j.cmd. I recently added support for passing linked lists and pointers to bash variables/functions into sourced C functions, and cd'ing around C pointer structure.
    #bash #sh #shellScripting #Linux #games #3D #Javascript #GLSL

  6. Need to create a bunch of files or directories on Linux each with a new number?

    🪄 A shell like bash can expand what is within the curly braces. You can even use steps en prefix with zeroes, so all names are equally long and easy to sort.

    💡 Good to know: not all shells support this, so be careful in scripts.

    🔁 #Linux #bash #shellscripting #automation

  7. Need to create a bunch of files or directories on Linux each with a new number?

    🪄 A shell like bash can expand what is within the curly braces. You can even use steps en prefix with zeroes, so all names are equally long and easy to sort.

    💡 Good to know: not all shells support this, so be careful in scripts.

    🔁 #Linux #bash #shellscripting #automation

  8. Need to create a bunch of files or directories on Linux each with a new number?

    🪄 A shell like bash can expand what is within the curly braces. You can even use steps en prefix with zeroes, so all names are equally long and easy to sort.

    💡 Good to know: not all shells support this, so be careful in scripts.

    🔁 #Linux #bash #shellscripting #automation

  9. Need to create a bunch of files or directories on Linux each with a new number?

    🪄 A shell like bash can expand what is within the curly braces. You can even use steps en prefix with zeroes, so all names are equally long and easy to sort.

    💡 Good to know: not all shells support this, so be careful in scripts.

    🔁 #Linux #bash #shellscripting #automation

  10. Need to create a bunch of files or directories on Linux each with a new number?

    🪄 A shell like bash can expand what is within the curly braces. You can even use steps en prefix with zeroes, so all names are equally long and easy to sort.

    💡 Good to know: not all shells support this, so be careful in scripts.

    🔁 #Linux #bash #shellscripting #automation

  11. If someone wonders about this:
    : ${E:?This is an error message.}

    It is a POSIX feature for showing errors and exiting if a variable has no content.
    It has the benefit of printing the line number.

    It uses : so that ${} can run on its own. The E:? checks if a variable E has content, if not it Prints the error message and exits the current shell.

    The reason why I use E is because it shows like an error, but you can use ERROR too if that is more clear (and you are certain that variable is empty.
    #shellScripting #linux #bsd

  12. If someone wonders about this:
    : ${E:?This is an error message.}

    It is a POSIX feature for showing errors and exiting if a variable has no content.
    It has the benefit of printing the line number.

    It uses : so that ${} can run on its own. The E:? checks if a variable E has content, if not it Prints the error message and exits the current shell.

    The reason why I use E is because it shows like an error, but you can use ERROR too if that is more clear (and you are certain that variable is empty.
    #shellScripting #linux #bsd

  13. If someone wonders about this:
    : ${E:?This is an error message.}

    It is a POSIX feature for showing errors and exiting if a variable has no content.
    It has the benefit of printing the line number.

    It uses : so that ${} can run on its own. The E:? checks if a variable E has content, if not it Prints the error message and exits the current shell.

    The reason why I use E is because it shows like an error, but you can use ERROR too if that is more clear (and you are certain that variable is empty.
    #shellScripting #linux #bsd

  14. If someone wonders about this:
    : ${E:?This is an error message.}

    It is a POSIX feature for showing errors and exiting if a variable has no content.
    It has the benefit of printing the line number.

    It uses : so that ${} can run on its own. The E:? checks if a variable E has content, if not it Prints the error message and exits the current shell.

    The reason why I use E is because it shows like an error, but you can use ERROR too if that is more clear (and you are certain that variable is empty.
    #shellScripting #linux #bsd

  15. If someone wonders about this:
    : ${E:?This is an error message.}

    It is a POSIX feature for showing errors and exiting if a variable has no content.
    It has the benefit of printing the line number.

    It uses : so that ${} can run on its own. The E:? checks if a variable E has content, if not it Prints the error message and exits the current shell.

    The reason why I use E is because it shows like an error, but you can use ERROR too if that is more clear (and you are certain that variable is empty.
    #shellScripting #linux #bsd

  16. All my shell scripts start like this:

    This section removes all variables, functions and aliases with single letter identifiers:
    ```
    i="A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
    a b c d e f g h i j k l m n o p q r s t u v w x y z"
    eval "unset -f $i; unset $i; unalias $i" >/dev/null 2>&1; :
    ```
    This sections prevents this from running on shells that do not support local:
    ```
    (command -v local >/dev/null || exit;F(){ local i=1; };F;[ -z "$i" ] && exit) \
    || : ${E:?"This shell doesn't support local variables. This can't run on it."}
    ```
    The original directory the script was called from:
    `OG_PWD=$PWD`

    This process id:
    `PROC_PID=$$`

    The first command used to execute this script, Eg `bash ./script.sh` would yield 'bash', doing `./script.sh` would yield 'script.sh'.
    `PROC_COMM=$(ps -p $$ -o comm=)`

    The location of this source file:
    `SOURCE_FILE=$(readlink -f "$0") || : ${E:?readlink -f "$0" failed}`

    The directory of the source file, it also `cd`s to it to make sure it exists and to make relative path imports easier.
    SOURCE_PATH=$(dirname "$SOURCE_FILE") && cd "$SOURCE_PATH" || : ${E:?Failed cd}

    The path to the current shell running the script:
    `SHELL_PATH=$(x=$(command -v "$PROC_COMM" || command -v sh);readlink -f "$x")`

    #shellScripting #shell #linux

  17. All my shell scripts start like this:

    This section removes all variables, functions and aliases with single letter identifiers:
    ```
    i="A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
    a b c d e f g h i j k l m n o p q r s t u v w x y z"
    eval "unset -f $i; unset $i; unalias $i" >/dev/null 2>&1; :
    ```
    This sections prevents this from running on shells that do not support local:
    ```
    (command -v local >/dev/null || exit;F(){ local i=1; };F;[ -z "$i" ] && exit) \
    || : ${E:?"This shell doesn't support local variables. This can't run on it."}
    ```
    The original directory the script was called from:
    `OG_PWD=$PWD`

    This process id:
    `PROC_PID=$$`

    The first command used to execute this script, Eg `bash ./script.sh` would yield 'bash', doing `./script.sh` would yield 'script.sh'.
    `PROC_COMM=$(ps -p $$ -o comm=)`

    The location of this source file:
    `SOURCE_FILE=$(readlink -f "$0") || : ${E:?readlink -f "$0" failed}`

    The directory of the source file, it also `cd`s to it to make sure it exists and to make relative path imports easier.
    SOURCE_PATH=$(dirname "$SOURCE_FILE") && cd "$SOURCE_PATH" || : ${E:?Failed cd}

    The path to the current shell running the script:
    `SHELL_PATH=$(x=$(command -v "$PROC_COMM" || command -v sh);readlink -f "$x")`

    #shellScripting #shell #linux

  18. All my shell scripts start like this:

    This section removes all variables, functions and aliases with single letter identifiers:
    ```
    i="A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
    a b c d e f g h i j k l m n o p q r s t u v w x y z"
    eval "unset -f $i; unset $i; unalias $i" >/dev/null 2>&1; :
    ```
    This sections prevents this from running on shells that do not support local:
    ```
    (command -v local >/dev/null || exit;F(){ local i=1; };F;[ -z "$i" ] && exit) \
    || : ${E:?"This shell doesn't support local variables. This can't run on it."}
    ```
    The original directory the script was called from:
    `OG_PWD=$PWD`

    This process id:
    `PROC_PID=$$`

    The first command used to execute this script, Eg `bash ./script.sh` would yield 'bash', doing `./script.sh` would yield 'script.sh'.
    `PROC_COMM=$(ps -p $$ -o comm=)`

    The location of this source file:
    `SOURCE_FILE=$(readlink -f "$0") || : ${E:?readlink -f "$0" failed}`

    The directory of the source file, it also `cd`s to it to make sure it exists and to make relative path imports easier.
    SOURCE_PATH=$(dirname "$SOURCE_FILE") && cd "$SOURCE_PATH" || : ${E:?Failed cd}

    The path to the current shell running the script:
    `SHELL_PATH=$(x=$(command -v "$PROC_COMM" || command -v sh);readlink -f "$x")`

    #shellScripting #shell #linux

  19. All my shell scripts start like this:

    This section removes all variables, functions and aliases with single letter identifiers:
    ```
    i="A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
    a b c d e f g h i j k l m n o p q r s t u v w x y z"
    eval "unset -f $i; unset $i; unalias $i" >/dev/null 2>&1; :
    ```
    This sections prevents this from running on shells that do not support local:
    ```
    (command -v local >/dev/null || exit;F(){ local i=1; };F;[ -z "$i" ] && exit) \
    || : ${E:?"This shell doesn't support local variables. This can't run on it."}
    ```
    The original directory the script was called from:
    `OG_PWD=$PWD`

    This process id:
    `PROC_PID=$$`

    The first command used to execute this script, Eg `bash ./script.sh` would yield 'bash', doing `./script.sh` would yield 'script.sh'.
    `PROC_COMM=$(ps -p $$ -o comm=)`

    The location of this source file:
    `SOURCE_FILE=$(readlink -f "$0") || : ${E:?readlink -f "$0" failed}`

    The directory of the source file, it also `cd`s to it to make sure it exists and to make relative path imports easier.
    SOURCE_PATH=$(dirname "$SOURCE_FILE") && cd "$SOURCE_PATH" || : ${E:?Failed cd}

    The path to the current shell running the script:
    `SHELL_PATH=$(x=$(command -v "$PROC_COMM" || command -v sh);readlink -f "$x")`

    #shellScripting #shell #linux

  20. All my shell scripts start like this:

    This section removes all variables, functions and aliases with single letter identifiers:
    ```
    i="A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
    a b c d e f g h i j k l m n o p q r s t u v w x y z"
    eval "unset -f $i; unset $i; unalias $i" >/dev/null 2>&1; :
    ```
    This sections prevents this from running on shells that do not support local:
    ```
    (command -v local >/dev/null || exit;F(){ local i=1; };F;[ -z "$i" ] && exit) \
    || : ${E:?"This shell doesn't support local variables. This can't run on it."}
    ```
    The original directory the script was called from:
    `OG_PWD=$PWD`

    This process id:
    `PROC_PID=$$`

    The first command used to execute this script, Eg `bash ./script.sh` would yield 'bash', doing `./script.sh` would yield 'script.sh'.
    `PROC_COMM=$(ps -p $$ -o comm=)`

    The location of this source file:
    `SOURCE_FILE=$(readlink -f "$0") || : ${E:?readlink -f "$0" failed}`

    The directory of the source file, it also `cd`s to it to make sure it exists and to make relative path imports easier.
    SOURCE_PATH=$(dirname "$SOURCE_FILE") && cd "$SOURCE_PATH" || : ${E:?Failed cd}

    The path to the current shell running the script:
    `SHELL_PATH=$(x=$(command -v "$PROC_COMM" || command -v sh);readlink -f "$x")`

    #shellScripting #shell #linux

  21. 🧰 The awk command is like a Swiss army knife but for data. So if you handle file data now and then, it is worth learning and practice with it.

    Awk is great on the command line, but also if you create some shellscript to automate a task 🤖

    For example, it can quickly filter out any long (or short) lines of a file.

    💡 Good to know: awk is available on most Unix-like systems, but their implementation differs a little bit.

    #shellscripting #awk #Linux #bsd

  22. 🧰 The awk command is like a Swiss army knife but for data. So if you handle file data now and then, it is worth learning and practice with it.

    Awk is great on the command line, but also if you create some shellscript to automate a task 🤖

    For example, it can quickly filter out any long (or short) lines of a file.

    💡 Good to know: awk is available on most Unix-like systems, but their implementation differs a little bit.

    #shellscripting #awk #Linux #bsd

  23. 🧰 The awk command is like a Swiss army knife but for data. So if you handle file data now and then, it is worth learning and practice with it.

    Awk is great on the command line, but also if you create some shellscript to automate a task 🤖

    For example, it can quickly filter out any long (or short) lines of a file.

    💡 Good to know: awk is available on most Unix-like systems, but their implementation differs a little bit.

    #shellscripting #awk #Linux #bsd

  24. 🧰 The awk command is like a Swiss army knife but for data. So if you handle file data now and then, it is worth learning and practice with it.

    Awk is great on the command line, but also if you create some shellscript to automate a task 🤖

    For example, it can quickly filter out any long (or short) lines of a file.

    💡 Good to know: awk is available on most Unix-like systems, but their implementation differs a little bit.

    #shellscripting #awk #Linux #bsd

  25. 🧰 The awk command is like a Swiss army knife but for data. So if you handle file data now and then, it is worth learning and practice with it.

    Awk is great on the command line, but also if you create some shellscript to automate a task 🤖

    For example, it can quickly filter out any long (or short) lines of a file.

    💡 Good to know: awk is available on most Unix-like systems, but their implementation differs a little bit.

    #shellscripting #awk #Linux #bsd

  26. I have managed a single PS1 that works across most bournelike shells :3
    And it prints the red ? when the previous command failed too!
    #linux #shellScripting

  27. I have managed a single PS1 that works across most bournelike shells :3
    And it prints the red ? when the previous command failed too!
    #linux #shellScripting

  28. I have managed a single PS1 that works across most bournelike shells :3
    And it prints the red ? when the previous command failed too!
    #linux #shellScripting

  29. I have managed a single PS1 that works across most bournelike shells :3
    And it prints the red ? when the previous command failed too!
    #linux #shellScripting

  30. I have managed a single PS1 that works across most bournelike shells :3
    And it prints the red ? when the previous command failed too!
    #linux #shellScripting

  31. Think I've got enough #ksh implementations installed? XD

    rld@Intrepid:~$ pkg info |grep ksh
    ksh-1.0.10                     ksh93u+m is the renewed development of ksh93 based on AT&T ksh93u+m (stable)
    mksh-59c_3                     MirBSD Korn Shell
    oksh-7.8,1                     Portable OpenBSD Korn shell
    pdksh-5.2.14p2_7               The Public Domain Korn Shell
    rld@Intrepid:~$ 
    

    #mksh #pdksh #oksh #testing #unix #unixShell #ShellScripting

  32. Think I've got enough #ksh implementations installed? XD

    rld@Intrepid:~$ pkg info |grep ksh
    ksh-1.0.10                     ksh93u+m is the renewed development of ksh93 based on AT&T ksh93u+m (stable)
    mksh-59c_3                     MirBSD Korn Shell
    oksh-7.8,1                     Portable OpenBSD Korn shell
    pdksh-5.2.14p2_7               The Public Domain Korn Shell
    rld@Intrepid:~$ 
    

    #mksh #pdksh #oksh #testing #unix #unixShell #ShellScripting

  33. Think I've got enough #ksh implementations installed? XD

    rld@Intrepid:~$ pkg info |grep ksh
    ksh-1.0.10                     ksh93u+m is the renewed development of ksh93 based on AT&T ksh93u+m (stable)
    mksh-59c_3                     MirBSD Korn Shell
    oksh-7.8,1                     Portable OpenBSD Korn shell
    pdksh-5.2.14p2_7               The Public Domain Korn Shell
    rld@Intrepid:~$ 
    

    #mksh #pdksh #oksh #testing #unix #unixShell #ShellScripting

  34. Think I've got enough #ksh implementations installed? XD

    rld@Intrepid:~$ pkg info |grep ksh
    ksh-1.0.10                     ksh93u+m is the renewed development of ksh93 based on AT&T ksh93u+m (stable)
    mksh-59c_3                     MirBSD Korn Shell
    oksh-7.8,1                     Portable OpenBSD Korn shell
    pdksh-5.2.14p2_7               The Public Domain Korn Shell
    rld@Intrepid:~$ 
    

    #mksh #pdksh #oksh #testing #unix #unixShell #ShellScripting

  35. Think I've got enough #ksh implementations installed? XD

    rld@Intrepid:~$ pkg info |grep ksh
    ksh-1.0.10                     ksh93u+m is the renewed development of ksh93 based on AT&T ksh93u+m (stable)
    mksh-59c_3                     MirBSD Korn Shell
    oksh-7.8,1                     Portable OpenBSD Korn shell
    pdksh-5.2.14p2_7               The Public Domain Korn Shell
    rld@Intrepid:~$ 
    

    #mksh #pdksh #oksh #testing #unix #unixShell #ShellScripting

  36. In the #shell #functions I should have written years ago category...

    function fedilinktousername {
        grep -oE 'https?://[^/]+/@[^/ ]+' |sed -E 's|https?://|@|; s|/@|@|; s/(@[^@]*)(@[^@]*)/\2\1/'
    }
    
    function fediusernametolink {
        grep -oE '(@[^@ ]+){2}' |sed -E 's|(@[^@ ]+)@([^@ ]+)|https://\2/\1|'
    }
    
    rld@Intrepid:~$ clipo
    https://polymaths.social/@rl_dane/statuses/01KVJCAG6Y4C1KTGBDBECH2778
    rld@Intrepid:~$ clipo |fedilinktousername 
    @[email protected]
    rld@Intrepid:~$ clipo |fedilinktousername |fediusernametolink 
    https://polymaths.social/@rl_dane
    rld@Intrepid:~$ 
    

    #UnixShell #ShellScripting #Unix #bash #ksh

  37. In the #shell #functions I should have written years ago category...

    function fedilinktousername {
        grep -oE 'https?://[^/]+/@[^/ ]+' |sed -E 's|https?://|@|; s|/@|@|; s/(@[^@]*)(@[^@]*)/\2\1/'
    }
    
    function fediusernametolink {
        grep -oE '(@[^@ ]+){2}' |sed -E 's|(@[^@ ]+)@([^@ ]+)|https://\2/\1|'
    }
    
    rld@Intrepid:~$ clipo
    https://polymaths.social/@rl_dane/statuses/01KVJCAG6Y4C1KTGBDBECH2778
    rld@Intrepid:~$ clipo |fedilinktousername 
    @[email protected]
    rld@Intrepid:~$ clipo |fedilinktousername |fediusernametolink 
    https://polymaths.social/@rl_dane
    rld@Intrepid:~$ 
    

    #UnixShell #ShellScripting #Unix #bash #ksh

  38. In the #shell #functions I should have written years ago category...

    function fedilinktousername {
        grep -oE 'https?://[^/]+/@[^/ ]+' |sed -E 's|https?://|@|; s|/@|@|; s/(@[^@]*)(@[^@]*)/\2\1/'
    }
    
    function fediusernametolink {
        grep -oE '(@[^@ ]+){2}' |sed -E 's|(@[^@ ]+)@([^@ ]+)|https://\2/\1|'
    }
    
    rld@Intrepid:~$ clipo
    https://polymaths.social/@rl_dane/statuses/01KVJCAG6Y4C1KTGBDBECH2778
    rld@Intrepid:~$ clipo |fedilinktousername 
    @[email protected]
    rld@Intrepid:~$ clipo |fedilinktousername |fediusernametolink 
    https://polymaths.social/@rl_dane
    rld@Intrepid:~$ 
    

    #UnixShell #ShellScripting #Unix #bash #ksh

  39. In the #shell #functions I should have written years ago category...

    function fedilinktousername {
        grep -oE 'https?://[^/]+/@[^/ ]+' |sed -E 's|https?://|@|; s|/@|@|; s/(@[^@]*)(@[^@]*)/\2\1/'
    }
    
    function fediusernametolink {
        grep -oE '(@[^@ ]+){2}' |sed -E 's|(@[^@ ]+)@([^@ ]+)|https://\2/\1|'
    }
    
    rld@Intrepid:~$ clipo
    https://polymaths.social/@rl_dane/statuses/01KVJCAG6Y4C1KTGBDBECH2778
    rld@Intrepid:~$ clipo |fedilinktousername 
    @[email protected]
    rld@Intrepid:~$ clipo |fedilinktousername |fediusernametolink 
    https://polymaths.social/@rl_dane
    rld@Intrepid:~$ 
    

    #UnixShell #ShellScripting #Unix #bash #ksh

  40. In the #shell #functions I should have written years ago category...

    function fedilinktousername {
        grep -oE 'https?://[^/]+/@[^/ ]+' |sed -E 's|https?://|@|; s|/@|@|; s/(@[^@]*)(@[^@]*)/\2\1/'
    }
    
    function fediusernametolink {
        grep -oE '(@[^@ ]+){2}' |sed -E 's|(@[^@ ]+)@([^@ ]+)|https://\2/\1|'
    }
    
    rld@Intrepid:~$ clipo
    https://polymaths.social/@rl_dane/statuses/01KVJCAG6Y4C1KTGBDBECH2778
    rld@Intrepid:~$ clipo |fedilinktousername 
    @[email protected]
    rld@Intrepid:~$ clipo |fedilinktousername |fediusernametolink 
    https://polymaths.social/@rl_dane
    rld@Intrepid:~$ 
    

    #UnixShell #ShellScripting #Unix #bash #ksh

  41. Seriously, why didn't I put this in my ~/.bashrc like... YEARS ago? 😆

    year=$( date +%Y)
    month=$(date +%m)
    day=$(  date +%d)
    

    #Unix #UnixShell #shell #ShellScripting #bash #bashrc

  42. Seriously, why didn't I put this in my ~/.bashrc like... YEARS ago? 😆

    year=$( date +%Y)
    month=$(date +%m)
    day=$(  date +%d)
    

    #Unix #UnixShell #shell #ShellScripting #bash #bashrc

  43. Seriously, why didn't I put this in my ~/.bashrc like... YEARS ago? 😆

    year=$( date +%Y)
    month=$(date +%m)
    day=$(  date +%d)
    

    #Unix #UnixShell #shell #ShellScripting #bash #bashrc

  44. Seriously, why didn't I put this in my ~/.bashrc like... YEARS ago? 😆

    year=$( date +%Y)
    month=$(date +%m)
    day=$(  date +%d)
    

    #Unix #UnixShell #shell #ShellScripting #bash #bashrc

  45. Seriously, why didn't I put this in my ~/.bashrc like... YEARS ago? 😆

    year=$( date +%Y)
    month=$(date +%m)
    day=$(  date +%d)
    

    #Unix #UnixShell #shell #ShellScripting #bash #bashrc

  46. Some POSIX #ShellScripting resources I've had bookmarked since before the question #WhyTheFuckDoesAIHaveToRuinEverything needed to be asked:

    Rich’s sh (POSIX shell) tricks: etalabs.net/sh_tricks.html

    GitHub - dylanaraps/pure-sh-bible: 📖 A collection of pure POSIX sh alternatives to external processes. · GitHub: github.com/dylanaraps/pure-sh-

    POSIX Shell Tutorial: grymoire.com/Unix/Sh.html

    #Computers #Programming #Linux

  47. Some POSIX #ShellScripting resources I've had bookmarked since before the question #WhyTheFuckDoesAIHaveToRuinEverything needed to be asked:

    Rich’s sh (POSIX shell) tricks: etalabs.net/sh_tricks.html

    GitHub - dylanaraps/pure-sh-bible: 📖 A collection of pure POSIX sh alternatives to external processes. · GitHub: github.com/dylanaraps/pure-sh-

    POSIX Shell Tutorial: grymoire.com/Unix/Sh.html

    #Computers #Programming #Linux

  48. Some POSIX #ShellScripting resources I've had bookmarked since before the question #WhyTheFuckDoesAIHaveToRuinEverything needed to be asked:

    Rich’s sh (POSIX shell) tricks: etalabs.net/sh_tricks.html

    GitHub - dylanaraps/pure-sh-bible: 📖 A collection of pure POSIX sh alternatives to external processes. · GitHub: github.com/dylanaraps/pure-sh-

    POSIX Shell Tutorial: grymoire.com/Unix/Sh.html

    #Computers #Programming #Linux

  49. Some POSIX #ShellScripting resources I've had bookmarked since before the question #WhyTheFuckDoesAIHaveToRuinEverything needed to be asked:

    Rich’s sh (POSIX shell) tricks: etalabs.net/sh_tricks.html

    GitHub - dylanaraps/pure-sh-bible: 📖 A collection of pure POSIX sh alternatives to external processes. · GitHub: github.com/dylanaraps/pure-sh-

    POSIX Shell Tutorial: grymoire.com/Unix/Sh.html

    #Computers #Programming #Linux

  50. Day 2/60 #BashSecurity -- Variables and types

    Bash's "type system" is: everything is a string. This causes real security issues.

    ```bash
    # This is an injection vulnerability:
    user_in="file.txt; cat /etc/shadow"
    grep $user_in /var/log/auth.log

    # This is safe:
    grep "$user_in" /var/log/auth.log
    ```

    Other gotchas:
    - `declare -i num=5; num="abc"` silently sets num to 0
    - `export SECRET` makes it readable via /proc/self/environ
    - `readonly CFG=/etc/app` prevents runtime tampering
    - `x = 5` (with spaces) runs x as a command, not assignment

    Quote every expansion. Validate every input. Trust nothing.

    #InfoSec #CyberSecurity #Linux #ShellScripting

  51. Wrote a #shell function without using ls inside of $( ), so my inner @mirabilos won't harass me. XD

    #slightly easier wireguard command
    function wg {
        local dir file profile profiledir= parm=${1:-} statustext
        #Find profile dir
        for dir in {,/usr/local}/etc/wireguard; do
            if [[ -d $dir ]]; then
                profiledir=$dir
                break
            fi
        done
        #Find config file
        if [[ -n $profiledir ]]; then
            for file in $profiledir/*.conf; do
                if [[ -e $file ]]; then
                    profile=${file//*\/}
                    profile=${profile/.conf}
                    break
                fi
            done
        fi
        [[ -n $profile ]] || profile=proton
        statustext="wireguard profile $profile"
        case ${parm,,} in
            up|on)      doas wg-quick  up  $profile;;
            down|off)   doas wg-quick down $profile;;
            status)     echo -en "$statustext _______\r"
                        echo -en "$statustext "
                        ifconfig |grep -q "^$profile:" && echo enabled || echo disabled;;
            *)          warn "wg usage: wg up|down|status";;
        esac
    }
    

    Hmm, seems ${foo,,} for lower case conversion is #bash-only. I wonder if I should use tr instead.

    #Unix #UnixShell #ShellScript #ShellScripting

  52. Wrote a #shell function without using ls inside of $( ), so my inner @mirabilos won't harass me. XD

    #slightly easier wireguard command
    function wg {
        local dir file profile profiledir= parm=${1:-} statustext
        #Find profile dir
        for dir in {,/usr/local}/etc/wireguard; do
            if [[ -d $dir ]]; then
                profiledir=$dir
                break
            fi
        done
        #Find config file
        if [[ -n $profiledir ]]; then
            for file in $profiledir/*.conf; do
                if [[ -e $file ]]; then
                    profile=${file//*\/}
                    profile=${profile/.conf}
                    break
                fi
            done
        fi
        [[ -n $profile ]] || profile=proton
        statustext="wireguard profile $profile"
        case ${parm,,} in
            up|on)      doas wg-quick  up  $profile;;
            down|off)   doas wg-quick down $profile;;
            status)     echo -en "$statustext _______\r"
                        echo -en "$statustext "
                        ifconfig |grep -q "^$profile:" && echo enabled || echo disabled;;
            *)          warn "wg usage: wg up|down|status";;
        esac
    }
    

    Hmm, seems ${foo,,} for lower case conversion is #bash-only. I wonder if I should use tr instead.

    #Unix #UnixShell #ShellScript #ShellScripting

  53. Wrote a #shell function without using ls inside of $( ), so my inner @mirabilos won't harass me. XD

    #slightly easier wireguard command
    function wg {
        local dir file profile profiledir= parm=${1:-} statustext
        #Find profile dir
        for dir in {,/usr/local}/etc/wireguard; do
            if [[ -d $dir ]]; then
                profiledir=$dir
                break
            fi
        done
        #Find config file
        if [[ -n $profiledir ]]; then
            for file in $profiledir/*.conf; do
                if [[ -e $file ]]; then
                    profile=${file//*\/}
                    profile=${profile/.conf}
                    break
                fi
            done
        fi
        [[ -n $profile ]] || profile=proton
        statustext="wireguard profile $profile"
        case ${parm,,} in
            up|on)      doas wg-quick  up  $profile;;
            down|off)   doas wg-quick down $profile;;
            status)     echo -en "$statustext _______\r"
                        echo -en "$statustext "
                        ifconfig |grep -q "^$profile:" && echo enabled || echo disabled;;
            *)          warn "wg usage: wg up|down|status";;
        esac
    }
    

    Hmm, seems ${foo,,} for lower case conversion is #bash-only. I wonder if I should use tr instead.

    #Unix #UnixShell #ShellScript #ShellScripting

  54. @heinelo das kann ich gut nachvollziehen, allerdings würde ich auch ins Feld führen, daß #macos im Kern auch ein linuixes System ist und von daher so genutzt werden kann.
    In der graphischen Industrie sind #adobe Produkte einfach nicht weg zu denken. Deswegen verwende ich meine #mac Rechner eher wie #opensource Plattformen. Installationen werden mit #shellscripting erledigt und Programme mit #homebrew installiert.
    Ich verwende keine AppleIDs, eigene Clouds, Aressbücher, Kalender und einen eigenen Mailserver bei Kunden und bei mir selbst.
    So finde ich ist ein #macos ein unabhängiges System, welches auch keinem #killswitch ausgesetzt sein wird, denn sollte sich Apple dazu entscheiden keine Updates mehr zu liefern – was ich nicht glaube – dann installiere ich mir auf den Geräten #Linux, was ich eh schon mit meinen alten #apple Rechnern gemacht habe.

  55. @heinelo das kann ich gut nachvollziehen, allerdings würde ich auch ins Feld führen, daß #macos im Kern auch ein linuixes System ist und von daher so genutzt werden kann.
    In der graphischen Industrie sind #adobe Produkte einfach nicht weg zu denken. Deswegen verwende ich meine #mac Rechner eher wie #opensource Plattformen. Installationen werden mit #shellscripting erledigt und Programme mit #homebrew installiert.
    Ich verwende keine AppleIDs, eigene Clouds, Aressbücher, Kalender und einen eigenen Mailserver bei Kunden und bei mir selbst.
    So finde ich ist ein #macos ein unabhängiges System, welches auch keinem #killswitch ausgesetzt sein wird, denn sollte sich Apple dazu entscheiden keine Updates mehr zu liefern – was ich nicht glaube – dann installiere ich mir auf den Geräten #Linux, was ich eh schon mit meinen alten #apple Rechnern gemacht habe.

  56. @heinelo das kann ich gut nachvollziehen, allerdings würde ich auch ins Feld führen, daß #macos im Kern auch ein linuixes System ist und von daher so genutzt werden kann.
    In der graphischen Industrie sind #adobe Produkte einfach nicht weg zu denken. Deswegen verwende ich meine #mac Rechner eher wie #opensource Plattformen. Installationen werden mit #shellscripting erledigt und Programme mit #homebrew installiert.
    Ich verwende keine AppleIDs, eigene Clouds, Aressbücher, Kalender und einen eigenen Mailserver bei Kunden und bei mir selbst.
    So finde ich ist ein #macos ein unabhängiges System, welches auch keinem #killswitch ausgesetzt sein wird, denn sollte sich Apple dazu entscheiden keine Updates mehr zu liefern – was ich nicht glaube – dann installiere ich mir auf den Geräten #Linux, was ich eh schon mit meinen alten #apple Rechnern gemacht habe.

  57. Recursion usually scares me a bit, but it worked out nicely here:

    #convert "cx"-style Esperanto notation to native accents (ĉ)
    function eaccent {
        if [[ ${1:-} ]]; then
            echo "$*" |eaccent
        else
            sed 's/cx/ĉ/g; s/gx/ĝ/g; s/hx/ĥ/g; s/jx/ĵ/g; s/sx/ŝ/g; s/ux/ŭ/g; s/C[xX]/Ĉ/g; s/G[xX]/Ĝ/g; s/H[xX]/Ĥ/g; s/J[xX]/Ĵ/g; s/S[xX]/Ŝ/g; s/U[xX]/Ŭ/g'
        fi
    }
    

    #bash #unix #shell #scripts #scripting #UnixShell #ShellScripting #Esperanto