===== Links ===== Terminals: * [[habrahabr>164687|Альтернативный терминал для Windows]] * [[habrahabr>176077|Интересная замена стандартного терминала: Terminology]] * [[habrahabr>185944|Final Term: новый взгляд на терминал]] * [[habrahabr>248881|Обзор Friendly interactive shell (fish) и почему она лучше bash]] * [[habrahabr>204368|Linux-like терминал в Windows]] * [[http://software.jessies.org/terminator/|Terminator]] -- a cross-platform (Java) GPL terminal emulator with advanced features Shells: * [[https://packages.debian.org/jessie/shells/|Shells in Debian]] * [[http://fishshell.com/|Fish]] -- smart and user-friendly command line shell * [[habrahabr>267797|Консоль 21 века: mosh, tmux, fish]] Other tips: * [[http://www.spinics.net/lists/util-linux-ng/msg13866.html|New ''columns'' syntax]] ===== Questions answered ===== === How to use variable in while loop? === The following scripts do not work properly: * VAR=0 ls -1 | while read file do [ "$file" = "tmp" ] && VAR=1 done echo $VAR # It turns out that $VAR is always zero here * echo "tmp.txt" | read file If ''while'' loop consumes the input from the pipe, it is launched in a subshell, thus all changes to the variables inside the loop do not work as expected (are not propagated to calling shell). Solution: loop should be executed by primary shell: - From [[stackoverflowa>16855194/267197|Modifying variable inside while loop is not remembered]]: VAR=0 while read file do [ "$file" = "tmp" ] && VAR=1 done < <(ls -1) Process substitution which is used in above example, is described [[http://wiki.bash-hackers.org/syntax/expansion/proc_subst|here]]. Another good application of process substitution is [[stackoverflowa>43972501/267197|capturing the exit code of first command in a pipe]]: if mount /dev/sda /mnt 2> >(head -1) then ... fi The same way ''read'' and ''arrayread'' when applied after the pipe initialize the variable in a forked shell (hence ''echo file.txt | read line'' does not work) so the solution looks this: read file < <(echo file.txt) - From [[http://unix.stackexchange.com/questions/197121/|Create variables and assign values via loop]]: VAR=0 for file in $(ls -1) do [ "$file" = "tmp" ] && VAR=1 done === [[stackoverflowa>22439016/267197|How to evaluate the intersection of two lists]]? === [[wp>Intersection (set theory)|Intersection]] of two lists: * ''cat 1.txt 2.txt | sort | uniq -d'' * ''comm -12 1.txt 2.txt'' [[wp>Symmetric difference]] of two lists: * ''cat 1.txt 2.txt | sort | uniq -u'' === How to redirect output to STDERR? === * ''%%( >&2 echo "bla-bla" );%%'' * ''%%echo "bla-bla" > /dev/stderr%%'' * ''%%... | tee /dev/stderr | ...%%'' === How to initialize variable with //here//-document? === From [[stackoverflow>1167746|How to assign a heredoc value to a variable in Bash]]: read -r -d '' SCRIPT <<'EOS' use strict; my $lines = 0; while (<>) { chomp; $files++; } print "Number of lines: $lines\n"; EOS perl -e "$SCRIPT" === [[stackoverflow>604864|How to skip 1st line of output?]] === ''%%... | tail -n +2%%'' === How to read lines from file preserving leading spaces and without splitting? === From [[stackoverflowa>7314111/267197|Use bash to read line by line and keep space]] and [[stackoverflowa>29689199/267197|Bash read line does not read leading spaces]]: while IFS= read -r line do echo "$line" done < some_file.txt Similarly to read the whole file into variable: IFS= FILE=`cat some_file` === How to list files with their sizes and MD5 sum? === ( echo -e "File\tMD5\tSize\tCTime" find . -type f -printf '%p\t%s\t%T+\n' | sort -k1 -t$'\t' | while IFS= read -r line do echo -e "$(md5sum "`echo "$line" | cut -f1`" | cut -f1 -d' ')\t$line"; \ done ) | column -t -s $'\t' See also: * [[https://unix.stackexchange.com/questions/57222|How can I use column to delimit on tabs and not spaces?]], [[https://unix.stackexchange.com/questions/35369|How to define 'tab' delimiter for 'cut'?]] * [[https://unix.stackexchange.com/questions/118433|Quoting within $(command substitution) in Bash]] === How to feed file names containing space to ''xargs''? === [[stackoverflowa>17325825/267197|How can I use xargs to copy files that have spaces and quotes in their names]] actually says that ''xargs'' should be tweaked, but if the list is produced by ''find'' then solutions are: * Use null separator: ''%%find ... -print0 | xargs -0 wc -l%%'' * Use ''find'' ability to append arguments: ''%%find ... -exec wc -l {} +%%'' === [[stackoverflowa>451204/267197|How to sum sequence of numbers?]] === seq 1 10 | paste -s -d+ | bc === [[https://unix.stackexchange.com/a/18742/36095|How to count number of specific characters in the file?]] === $ cat file | tr -d -c '#' | wc -c === [[stackoverflow>2172352|How to check if a string begins or ends with some value?]] === See [[http://tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS|Advanced Bash-Scripting Guide, Chapter 7]]: if [[ $fullpath == *.txt ]] then echo "This is text file" fi === How to extract filename and extension? === From [[stackoverflow>965053|Extract filename and extension in bash]]: file=`basename "$fullpath"` extension=${file##*.} filename=${file%.*} === [[stackoverflow>6426142|How to append/prepend the string to each array element?]] === array=( "${array[@]/#/prefix_}" ) array=( "${array[@]/%/_suffix}" ) To print an array as new-line separated string: IFS=$'\n' echo "${array[*]}" IFS=$'\n' echo "$*" | xargs ... === How to generate random strings? === To generate e.g. 5 random passwords each having 16 characters in alphabet "A-Za-z0-9" use: tr -dc A-Za-z0-9 < /dev/urandom | fold -w 16 | head -5 === [[http://unix.stackexchange.com/a/4035/36095|How to re-attach the process to another terminal?]] === $ myprog # press Ctrl+Z to suspend the program $ bg $ disown # switch to another terminal / screen / tmux session $ reptyr $(pgrep myprog) === How to turn off bell? === To disable bash from sending bell to terminal add/uncomment the following in ''~/.bashrc'': set bell-style none However bell can be useful to notify long running task: * [[stackoverflowa>7895288/267197|Configure PuTTY to flash Windows taskbar on bell]] * Latest ConEmu (v170807) supports this out-of-box unless //Disable all flashing// is not enabled in //[[https://conemu.github.io/en/SettingsFeatures.html|Settings → Features]]//. === [[http://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe|Turn off buffering for pipe]] === When data is output to stdout, one can see the result immediately (it flushes after each write). However if output is piped to another command, it is buffered, thus causing difficulties e.g. with ''tee'' utility. The problem is solved using ''stdbuf'' utility: stdbuf -oL tail -f /var/log/messages | tee logs.txt === [[habrahabr>148988|Можно ли в UNIX обнулять (truncate) файл, в который пишет некоторый процесс?]] ===
Таким образом, оболочки sh и csh, а также tcsh при открытии нового файла, не используют флаг ''O_APPEND'', а описанный выше способ обнуления используемых файлов в этих оболочках использовать не получится. В более современных оболочках (ksh, bash, zsh) этой проблемы нет.
{{tag>terminal shell}}