Hot answers tagged

42

In string: rtsp://user:pass@my.webserver.org:5554/my-media/media.amp?videocodec=h264 you have ? in that string, so the shell will perform pathname expansion on that string, using pattern matching rules. In bash, if failglob options was not set, which is default, then failed pattern will be left as-is: $ echo does-not-exist? does-not-exist? While zsh ...


19

Virtually all shell arrays (Bourne, csh, tcsh, fish, rc, es, yash) start at 1. ksh is the only exception that I know (bash just copied ksh). Most interpreted languages at the time (early 90s): awk, tcl at least, and tools typically used from the shell (cut -f1-3, head -n 3, sort -k1,3, cal 1 2015, comm -1) start at 1. sed, ed, vi number their lines from 1... ...


17

That's because in <<< $line, bash does word splitting, (though not globbing) on $line as it's not quoted there and then joins the resulting words with the space character (and puts that in a temporary file followed by a newline character and makes that the stdin of cut). $ a=a,b,,c bash -c 'IFS=","; sed -n l <<< $a' a b c$ tab happens ...


16

It's not /usr/bin/[ in either of the shells. In Bash, you're using the built-in test/[ command, and similarly in zsh. The difference is that zsh also has an = expansion: =foo expands to the path to the foo executable. That means == is treated as trying to find a command called = in your PATH. Since that command doesn't exist, you get the error zsh: = not ...


14

You could put a shell wrapper around a call to python (put this in .zshrc or .bashrc... depending on your shell), python () { if [ "$1" = manage.py ]; then command python manage.py && xyz else command python "$@" fi } But I suspect you are better off changing manage.py to run xyz at the end (see python subprocess ...


13

What happens is that bash replaces the tabs with spaces. You can avoid this problem by saying "$line" instead, or by explicitly cutting on spaces.


10

The problem is that you're not quoting $line. To investigate, change the two scripts so they simply print $line: #!/usr/bin/env bash while read line; do echo $line done < "$1" and #!/usr/bin/env zsh while read line; do echo $line done < "$1" Now, compare their output: $ bash.sh input foo bar baz foo bar baz $ zsh.sh input foo bar ...


9

This is very well known problem which is even described in zsh manual under chapter ALIASING (see man zshmisc). The recomended way of dealing with it is to use function instead of alias: foo() { ls; } ; foo or even better in case of ls: foo() { ls -- "${@:-.}"; } ; foo ps. semicolon at the end of the function definition (list) and spaces are not ...


9

You can not do it. Because aliases were expanded only after history expansion and entire line was read in one go, so when foo was executed, the alias expansion process was gone, it's too late for the shell to recognize new alias. The best way you can do is defining alias in .zshrc or using function like jimmij's answer or using eval: alias foo=ls; eval ...


9

zsh -o SOURCE_TRACE From the zsh manual (zshoptions(1)): SOURCE_TRACE If set, zsh will print an informational message announcing the name of each file it loads.  The format of the output is similar to that for the XTRACE option, with the message <sourcetrace>.  A file may be loaded by the shell itself when it starts up and shuts ...


9

ksh93 has disciplines which are typically used for this kind of thing. With zsh, you could hijack the dynamic named directory feature: Define for instance: zsh_directory_name() { case $1 in (n) case $2 in (incr) reply=($((++incr))) esac esac } And then you can use ~[incr] to get an incremented $incr each time: $ echo ~[incr] ...


9

Use $^array. It turns the array into a sort of brace expansion of the array. As in when a=(foo bar baz), $^a would be a bit like {foo,bar,baz}. $ a=(foo bar baz) $ echo prefix${^a}suffix prefixfoosuffix prefixbarsuffix prefixbazsuffix For multiplexing arrays: $ a=(1 2 3) b=(a b c) $ echo $^a$^b 1a 1b 1c 2a 2b 2c 3a 3b 3c Naturally, if the prefix or ...


9

With zsh and with the mult_ios option on (on by default), in: echo hi 2>&1 1>/dev/null | cat The 1> /dev/null | cat is seen as a multiple redirection of echo's stdout. So echo's stdout is now redirected to both /dev/null and a pipe to cat (as if using tee). To cancel that multiple redirection, you can do: echo hi 2>&1 >&- >...


8

When you press Ctrl+Z in a terminal, this causes the foreground process group to receive the signal SIGTSTP (assuming the terminal is in cooked mode and the default key bindings are in place). If the process hasn't set a signal handler for SIGTSTP, this causes the process to be suspended (and even if the process has set a signal handler, it usually only does ...


8

The old-fashioned way was to use POSTEDIT POSTEDIT=$'\e[0m' (and by the way this isn't bash, don't use a DEBUG trap to simulate preexec: zsh is where it's from) but since zsh 4.3.11 you can use the command line syntax highlighting facility. Let your prompt care only about your prompt and set zle_highlight=(default:bold)


8

This seems to be from prezto defining a function overriding diff. It may well have a way of disabling that, but I don't know what it is. You have a few options: /usr/bin/diff or command diff will both run the diff command, rather than the function. unset -f diff will remove the diff function. You could put that in your shell configuration. As you've found, ...


7

You can combine parameter expansion with brace expansion. % foo=(d e f) $ echo {a,b,c}${^foo} ad bd cd ae be ce af bf cf If you don't want to define foo separately (as seems likely), you can use the following: $ echo {a,b,c}${^:-d e f} ad bd cd ae be ce af bf cf If you have the rcexpandparam option set, then you don't need the ^ in either example to ...


7

When you want aliases to have parameters you can use functions, e.g. $ gpdo () { git branch -d "$1" && git push --delete origin "$1" } Then you can do gpdo branch_name This is also useful for multiple commands although they can also be done with an alias with multiple &&s if there are no parameters and no conditional logic, looping, ...


7

I think the most plausible answer to this is the reverse array built-in from zsh If you have an array with 4 elements, lets say myvar=(1 2 3 4) and you want to access the 4th element it will be print $myvar[4], right? However, if you want to create a loop that will list the elements inside this array backwards, it's just a matter of using negative indexes: ...


6

Try using realpath: realpath --relative-to=/foo/bar/something /foo/hello/world For more examples, see: Convert absolute path into relative path given a current directory at SO


6

You can force the ZSH to clobber on redirect with: >! Same as >, except that the file is truncated to zero length if it exists, even if CLOBBER is unset. or >>! Same as >>, except that the file is created if it does not exist, even if CLOBBER is unset.


6

Having a global keybind to disown the foreground process is impossible: Keystrokes are received by the foreground process, not by the shell. You need to first suspend it with Ctrl+z if you want to disown it. However, turns out there's a zsh option to speed up disowning then continuing: With setopt AUTO_CONTINUE, disown will automatically also send SIGCONT. ...


6

By default the only environment variable that's transmitted over an SSH connection is TERM. You can pack information there but you've got to be sure that it'll be unpacked on the server side. The client can transmit other messages, but the server needs to be set up to accept them with an AcceptEnv directive in /etc/sshd_config. Under Debian and most ...


6

What you want is preexec hook function: preexec() { printf "\e[0m"; } Then before each command was executed, preexec will be run to reset your font to normal. So, to get the same prompt you show in your question, add these lines to your ~/.zshrc: autoload -U colors && colors PS1="%{$fg_bold[yellow]%}%n@%m %{$fg[blue]%}%~ \$ %{$reset_color%}%{$...


6

You can just remove .pdf to get the file's name without the extension and check for a file of that name with the .xoj extension: for f in *.pdf do if [ -f "${f%.pdf}".xoj ] then xournal "${f%.pdf}".xoj & else xournal "${f}" & fi done


6

Turns out they really are equivalent, according to man zshbuiltins (section "disown"): simply syntactic alternatives for the same operation. Anticlimactic…


6

I don't think you can, and I don't think it actually makes any difference. unset a a=x echo "${a[0]-not array}" x That does the same thing in either of ksh93 and bash. It looks like possibly all variables are arrays in those shells, or at least any regular variable which has not been assigned special attributes, but I didn't check much of that. The ...


6

!(pattern) is ksh glob syntax, in zsh, you use ^(pattern) to negate the matching when extendedglob enabled: setopt extendedglob print -rl -- ^(2test|3test) If you want to use ksh syntax, you need to enable kshglob: setopt kshglob print -rl -- !(2test|3test) You can also use the and-not/except operator: setopt extendedglob print -rl -- *test~[23]* (*...


6

When you use setopt extendedglob you can use ^(2test|3test) to remove all files except 2test and 3test: # setopt extendedglob # touch {1..10}test # rm ^(2test|3test) # ls 2test 3test ! is used by bash, zsh however uses ^.


6

for i in {01..20}; do #replace with your own range echo \ wp input csv "MyCSV$i.csv" directory_name done Comment out the echo line if it gives you the results you want. zsh, which you tagged your question with, has a shorter form: for i (MyCSV{01..20}.csv) wp input csv $i directory_name Or you could use its zargs function: autoload zargs # best ...



Only top voted, non community-wiki answers of a minimum length are eligible