153 Matching Annotations
  1. Last 7 days
  2. May 2023
    1. Eine neue, grundlegende Studie zu Klima-Reparationen ergibt, dass die größten Fosssilkonzerne jählich mindestens 209 Milliarden Dollar als Reparationen an von ihnen besonders geschädigte Communities zahlen müssen. Dabei sind Schäden wie der Verlust von Menschenleben und Zerstörung der Biodiversität nicht einberechnet. https://www.theguardian.com/environment/2023/may/19/fossil-fuel-firms-owe-climate-reparations-of-209bn-a-year-says-study

      Studie: Time to pay the piper: Fossil fuel companies’ reparations for climate damages https://www.cell.com/one-earth/fulltext/S2590-3322(23)00198-7

  3. Apr 2023
  4. Feb 2023
    1. De UvA gaat voorlopig geen nieuwe onderzoekssamenwerkingen met Shell of soortgelijke bedrijven aan.

      UvA gaat voorlopig geen nieuwe onderzoekssamenwerkingen met Shell of soorgelijke bedrijven aan.

  5. Dec 2022
    1. For sufficiently simple cases, just running a few commands sequentially, with no subshells, conditional logic, or loops, set -euo pipefail is sufficient (and make sure you use shellcheck -o all).

      Advice for when you can use shell scripts

  6. Nov 2022
    1. Bash maintains an internal hash of previously found executables in your path. In this case, it has details that at one time there was an executable at /usr/bin/siege, and reuses that path to avoid having to search again. You need to tell bash to manually rehash the path for siege like so: hash siege You can also clear all hashed locations: hash -r
    1. Remember there are two kinds of variable. Internal Variables and Environment Variables. PATH should be an environment variable.

      In my case, I was trying to debug which asdf not finding asdf, in a minimal shell.

      I had checked bash-5.1$ echo $PATH|grep asdf /home/tyler/.asdf/bin

      but ```

      The PATH environment variable

      env | /bin/grep PATH `` being empty was the key discovery here. Must have forgotten theexport`.

    2. All shells should tell you that your path is the same thing with BOTH of the two commands: # The PATH variable echo "$PATH" # The PATH environment variable env | /bin/grep PATH
    1. Auch der Standard weist in einem Halbzeitbericht zur COP27 darauf hin, wieviele Vertreter der Fossilindustrien an den Verhandlungen dürfen. Ein Hauptinteresse dabei ist es, durch Regeln zu verhindern, dass die selbst verursachten Emissionen wirksam reduziert werden müssen. Er verweist dabei auf Shells Einfluss bei der Formulierung des Aktikels 6 des Pariser Abkommens.

  7. Aug 2022
    1. “These ads are intended to create a clean warm glow about the companies concerned, giving them more social licence to operate,” said Doug Parr, chief scientist for Greenpeace UK

      Die Ausgaben sprechen dafür, dass diese Art von Kommunikation sehr wirksam ist. Auch das schafft eine fundamentale Assymetrie zwischen der Fossilindustrie und ihren Gegnern.

    1. $0 would be OK in most cases, some exceptions are, for instance, when the script you're executing is aliased (through alias in .bash_profile). You should really use $BASH_SOURCE variable, instead of $0.
    2. Using $0 does not work when the script is run using source script or . script; the name of the script is not available.
  8. Jul 2022
    1. Always use a while read construct: find . -name "*.txt" -print0 | while read -d $'\0' file do …code using "$file" done The loop will execute while the find command is executing. Plus, this command will work even if a file name is returned with whitespace in it. And, you won't overflow your command line buffer.
  9. Apr 2022
    1. You can close the single quotes before starting the double quotes and do the reverse at the end of that inner section to achieve what you want:

      This is how to use variable in single quotes. It works well also for tcsh.

  10. Mar 2022
    1. Just let it expand inside an array declaration's right side: list=(../smth*/) # grab the list echo "${#list[@]}" # print array length echo "${list[@]}" # print array elements for file in "${list[@]}"; do echo "$file"; done # loop over the array
  11. Feb 2022
  12. Sep 2021
    1. I think it's very confusing to overload common executables, such as yarn, in the /bin directory as I often put that bin directory first in my path. Thus, I'd unexpectedly get the bin/yarn rather than my system yarn, which I manage with yvm.
    1. One good use for /dev/tty is if you're trying to call an editor in a pipeline (e.g., with xargs). Since the standard input of xargs is some list of files rather than your terminal, just doing, e.g., | xargs emacs will screw up your terminal. Instead you can use | xargs sh -c 'emacs "$@" </dev/tty' emacs to connect the editor to your terminal even though the input of xargs is coming from elsewhere.
  13. Jun 2021
    1. Please make sure that your file(s) referenced in bin starts with #!/usr/bin/env node, otherwise the scripts are started without the node executable!
    1. Since looping over the positional parameters is such a common thing to do in scripts, for arg defaults to for arg in "$@". The double-quoted "$@" is special magic that causes each parameter to be used as a single word (or a single loop iteration). It's what you should be using at least 99% of the time.
    2. Bash (like all Bourne shells) has a special syntax for referring to the list of positional parameters one at a time, and $* isn't it. Neither is $@. Both of those expand to the list of words in your script's parameters, not to each parameter as a separate word.
    1. Instead of using a for loop, which will fail on spaces unless you redefine the IFS variable, I would recommend using a while loop combined with find.
    1. Different ways to prepend a line: (echo 'line to prepend';cat file)|sponge file sed -i '1iline to prepend' file # GNU sed -i '' $'1i\\\nline to prepend\n' file # BSD printf %s\\n 0a 'line to prepend' . w|ed -s file perl -pi -e 'print"line to prepend\n"if$.==1' file
    1. for cpp_file in *.cpp; do gcc -c $$cpp_file & done; wait This gives much finer control than make -j.
    2. There is one very important reason for enabling job control to be useful inside scripts: the side-effect it has of placing background processes in their own process groups. This makes it much, much easier to send signels to them and their children with one simple command: kill -<signal> -$pgid. All other ways of dealing with signaling entire trees of processes either involve elaborate (sometimes even recursive) functions, which are often bugnests, or risk killing the parent in the process (no pun intended).
    1. To avoid the problems with different versions of echo you may want to use printf instead. In contrast to echo printf always interprets \ sequences but doesn't automatically add a linefeed at the end so you have to append \n at the end if you want one.
    1. while (( "$#" )); do case "$1" in -a|--my-boolean-flag) MY_FLAG=0 shift ;; -b|--my-flag-with-argument) if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then MY_FLAG_ARG=$2 shift 2 else echo "Error: Argument for $1 is missing" >&2 exit 1 fi ;; -*|--*=) # unsupported flags echo "Error: Unsupported flag $1" >&2 exit 1 ;; *) # preserve positional arguments PARAMS="$PARAMS $1" shift ;; esacdone# set positional arguments in their proper placeeval set -- "$PARAMS"
  14. May 2021
    1. For filter-branch, using pipelines like git ls-files | grep -v ... | xargs -r git rm might be a reasonable workaround but can get unwieldy and isn't as straightforward for users; plus those commands are often operating-system specific (can you spot the GNUism in the snippet I provided?)
    1. However, the place where pip places that package might not be in your $PATH (thus requiring you to manually update your $PATH afterwards), and on windows the pip install might not take care of python-specific issues for you (see "Notes for Windows Users", above). As such, installation via package managers is recommended instead.
    1. the bullet-proof way to add a path (e.g., ~/opt/bin) to the PATH environment variable is PATH="${PATH:+${PATH}:}~/opt/bin"
    1. The command nix-shell will build the dependencies of the specified derivation, but not the derivation itself. It will then start an interactive shell in which all environment variables defined by the derivation path have been set to their corresponding values, and the script $stdenv/setup has been sourced. This is useful for reproducing the environment of a derivation for development.

      QUESTION: What exactly does nix-shell execute from the Nix expression (i.e., shell.nix, default.nix, etc.)?

      ANSWER: Based on my current understanding, the answer is everything. It calls $stdenv/setup (see annotation below) to set up the most basic environment variables (TODO: expand on this), and "injects" the most common tools (e.g., gcc, sed) into it.

      It also defines the phases (TODO: verify this) and builder functions, such as genericBuilder. For example, the default builder is just two lines:

      source $stdenv/setup

      TODO: pkgs/stdenv/generic/builder.sh is a mystery though.

      QUESTION: Once dropping into nix-shell, how do I know what phases to execute by looking at a default.nix? (E.g., [..]freeswitch/default.nix)

      ANSWER: As far as I can tell, one can override the phases in their Nix build expression (to build the derivation, see at the bottom), but they won't get executed as only the $stdenv/setup (see above) will get sourced, and no builders are called that, in return, invoke the phases (again, see above).

      So if one is using nix-shell

      • to create/hack on a package, the person has to manually invoke the builder or phases (TODO: still fuzzy on this subject)

      • to set up an environment, then one doesn't even have to worry about builders/phases because we just use nix-shell to clear the environment and to inject tools that we need for a given task

      QUESTION: When dropping into nix-shell, is this Nix expression (i.e., freeswitch/default.nix) executed? Or just parts of it?

      ANSWER: As stated above, all of the input Nix expression is evaluated, but no builders and build phases are called; although, nothing prevents one to override the phases, in case they are creating/hacking on a package.


      The command nix-shell will build the dependencies of the specified derivation, but not the derivation itself.

      What is the "derivation" here exactly? I know that it is a build expression, but does that mean the default.nix (or other Nix expression) nix-shell is invoked with?

      <sup>This statement also seems like a contradiction with how `nix-shell` works (i.e., if one issues `nix-shell -p curl`, then `curl` will be available in that sub-shell), but `-p` acts like a shortcut to as if `curl` had been listed in `buildInputs` so this is not the case.</sup>

      ANSWER: I have the feeling my confusion comes from the fact that the term "derivation" is used ambiguously in the manuals, sometimes to mean multiple things (see list below).

      TODO: Substantiate this claim, and make sure that it not coming from my misunderstanding certain topics.

      • Nix build expression (such as default.nix) whose output is going to become the store derivation itself (see last item at the bottom about the Nix manual's glossary definition)

      • store derivation.

      Had multiple cracks at unambiguously define what a derivation is, and here's a list of these:

      QUESTION: What is the difference between nix-shell -p and nix-shell invoked with a Nix expression of mkShell (or other that achieves the similar effect)?

      QUESTION: nix-shell does not create a sub-shell, so what does it do? (clarification: so nix-shell indeed does it; I confused it with nix shell)

  15. Apr 2021
    1. Write stderr and stdout to a file, display stderr on screen (on stdout) exec 2> >(tee -a -i "$HOME/somefile.log") exec >> "$HOME/somefile.log" Useful for crons, so you can receive errors (and only errors) by mail
    2. I just wanted to point out that the syntax is not supported by the POSIX standard and thus won't universally work in /bin/sh scripts (many people erroneously use bash syntax in /bin/sh scripts)
    3. exec > >(tee "$HOME/somefile.log") 2>&1
    1. When you have a pipeline, unbuffer must be applied to each element except the last (since that doesn't have its output redirected). Example: unbuffer p1 | unbuffer p2 | unbuffer p3 | p4
    1. empty is an utility that provides an interface to execute and/or interact with processes under pseudo-terminal sessions (PTYs). This tool is definitely useful in programming of shell scripts designed to communicate with interactive programs like telnet, ssh, ftp, etc.
    2. can be easily invoked directly from shell prompt or script

      Can't expect / unbuffer / etc. (whatever this is attempting to contrast itself with) be easily invoked directly from shell prompt or script too??

      Okay, I guess you have to know more about how expect is invoked to understand what they mean. One glance at the examples, comparing them, and all becomes clear:

      empty -f -i in -o out telnet foo.bar.com
      empty -w -i out -o in "ogin:" "luser\n"

      I didn't realize that expect required/expected (no pun intended) to be used in scripts with its own shebang line:

      spawn telnet foo.bar.com 
      expect ogin {send luser\r}

      That does make it less easy/normal to use expect within a shell script.

      I was coming to the expect project from/for the unbuffer command, which by contrast, is quite easy to include/use in a shell script -- almost the same as empty, in fact. (Seems like almost a mismatch to have unbuffer command in expect toolkit then. Or is expect command the only odd one out in that toolkit?)

    3. does not use TCL, Perl, PHP, Python or anything else as an underlying language is written entirely in C has small and simple source code can easily be ported to almost all UNIX-like systems
  16. Mar 2021
  17. Feb 2021
    1. Now this probably won't make difference in the real world (e.g. because the exit codes are not portable and on top of that not always unambiguous as discussed in Default exit code when process is terminated?)
    1. read -rep $'\nDo you wish to stop playing?(y/n)' yn
    2. You also need job controlled -monitoring in your parent so it keep track of its children. wait, for example, only works at all with job control. -monitor mode is how shells interact with terminals.
    1. The parentheses always start a subshell. What's happening is that bash detects that sleep 5 is the last command executed by that subshell, so it calls exec instead of fork+exec. The sleep command replaces the subshell in the same process.
    1. example: get an environment which is used to build irssi (also see nix-shell) $ nix-build $NIXPKGS --run-env -A irssi example: get a persistent environment which is used to build irssi $ nix-build $NIXPKGS --run-env -A irssi --add-root

      nix-build <path> --run-env has been superseded by nix-shell. From Nix manual section C.12. Release 1.6 (2013-09-10):

      The command nix-build --run-env has been renamed to nix-shell.

  18. Nov 2020
    1. The potential problem: if second_task fails, third_task will not run, and execution will continue to the next line of code - next_task, in this example. This may be exactly the behavior you want. Alternatively, you may be intending that if second_task fails, the script should immediately exit with its error code. In this case, the best choice is to use a block - i.e., curly braces: first_task && { second_task third_task } next_task Because we are using the -e option, if second_task fails, the script immediately exits.
    2. When people write COND && COMMAND, typically they mean "if COND succeeds (or is boolean true), then execute COMMAND. Regardless, proceed to the next line of the script." It's a very convenient shorthand for a full "if/then/fi" clause.
    1. zip -r myfile.zip ./filename

      把filename 压缩成 myfile.zip

      unzip -d /home/file myfile.zip

      把myfile.zip 压缩到 home/file 目录下

      zip -d myfile.zip smart.txt

      删除 myfile.zip 中的 smart.txt

      zip -m myfile.zip add.txt

      往 myfile.zip 中加 add.txt

    1. It starts truncating it's output (shortening strings with ...) once you pipe it's output into grep. That is quite unacceptable. When I am checking if something is inhibited in a script, I should have all possible information available and not have to consider if a string will get truncated when being piped into a tool, that is perfectly readable on a wide terminal.
  19. Oct 2020
    1. *

      * 应该表示当前文件夹内的文件, 类似于 ls

    2. begins with a special symbol: #. This marks the line as a comment

      以#开头的代码表示这行代码被注释掉了,这点跟 Python 一致。

    1. Note that to make a file executable, you must set the eXecutable bit, and for a shell script, the Readable bit must also be set:


    2. Shell Scripting Tutorial

      shell 编程教程

  20. Aug 2020
    1. You can also nest brace expansion lists in the mkdir command. For example, in the articles subdirectory under the htg directory, we want to create two subdirectories called new and rewritten. So, we type the following command at the prompt and press Enter. mkdir -p htg/{articles/{new,rewrites},images,notes,done}
  21. Jul 2020
    1. The most commonly supported tool for this is kerl. Kerl is a wrapper around downloading, compiling, and loading various Erlang/OTP versions on a single system, and will abstract away most annoying operations.
  22. Jun 2020
  23. May 2020
    1. I have used this bash one-liner before set -- "${@:1:$(($#-1))}" It sets the argument list to the current argument list, less the last argument.

      Analogue of shift built-in. Too bad there isn't just a pop built-in.

  24. Apr 2020
    1. Invert the exit code of a process. Make 0 into 1 and everything else into a 0. An alternative to ! some-command syntax present in some shells.
    1. # Add auto-completion and a stored history file of commands to your Python # interactive interpreter. Requires Python 2.0+, readline. Autocomplete is # bound to the Esc key by default (you can change it - see readline docs). # # Store the file in ~/.pystartup, and set an environment variable to point # to it: "export PYTHONSTARTUP=~/.pystartup" in bash. import atexit import os import readline import rlcompleter historyPath = os.path.expanduser("~/.pyhistory") def save_history(historyPath=historyPath): import readline readline.write_history_file(historyPath) if os.path.exists(historyPath): readline.read_history_file(historyPath) atexit.register(save_history) del os, atexit, readline, rlcompleter, save_history, historyPath

      Enable history and sane keys in python shell

  25. Feb 2020
  26. Jan 2020
    1. ps f

      this doesn't run on my system. However ps -f seems to list processes started in the terminal and ps -ef lists all (?) processes

  27. Dec 2019
    1. Point to be noted is, there is a backslash before curl. This prevents misbehaving if you have aliased it with configuration in your ~/.curlrc file.
    1. As for exec, I am just using it because it makes sense to run the final command in the same process, replacing the wrapper script instead of spawning a new process. It's not strictly necessary.
    1. For those (like me) wondering why is the space needed, man bash has this to say about it: > Note that a negative offset must be separated from the colon by at least one space to avoid being confused with the :- expansion.
    1. Do not start ssh-agent from .bashrc or .zshrc, since these files are executed by each new interactive shell. The place to start ssh-agent is in a session startup file such as .profile or .xsession.
  28. Nov 2019
  29. Sep 2019