Tag Info

Hot answers tagged

11

Without quotes the string is subject to word splitting and globbing. See also BashPitfalls #14. Compare $ echo $(printf 'foo\nbar\nquux\n*') foo bar quux ssh-13yzvBMwVYgn ssh-3JIxkphQ07Ei ssh-6YC5dbnk1wOc with $ echo "$(printf 'foo\nbar\nquux\n*')" foo bar quux * When word splitting occurs the first character of IFS acts as a separator (which, per ...


11

eval "$1" executes the command in the current script. It can set and use shell variables from the current script, set environment variables for the current script, set and use functions from the current script, set the current directory, umask, limits and other attributes for the current script, and so on. bash "$1" executes the command in a completely ...


8

The most important difference between bash -c "$1" And eval "$1" Is that the former runs in a subshell and the latter does not. So: set -- 'var=something' bash -c "$1" echo "$var" OUTPUT: #there doesn't seem to be anything here set -- 'var=something' eval "$1" echo "$var" OUTPUT: something I have no idea why anyone would ever use the ...


8

Borrowing from celtschk's answer, /dev/fd is a symbolic link to /proc/self/fd. And /proc is a pseudo filesystem, that presents information about processes and other system information in a hierarchical file-like structure. Files in /dev/fd correspond to files, opened by a process and has file descriptor as their names and files themselves as their targets. ...


7

Well, there are many aspects to it. File descriptors For each process, the kernel maintains a table of open files (well, it might be implemented differently, but since you are not able to see it anyways, you can just assume it's a simple table). That table contains information about which file it is/where it can be found, in which mode you opened it, at ...


7

I am not sure what exactly happened. What happened was that the file was rotated by an external application. This is usual. Utilities like logrotate rotate log files, i.e. the contents of the existing log file are moved to another file and the existing one is blanked out before an application starts writing to it again. When tail determines that the ...


7

To get the same output you note in your question, all that is needed is this: PS1='${PS2c##*[$((PS2c=0))-9]}- > ' PS2='$((PS2c=PS2c+1)) > ' You need not contort. Those two lines will do it all in any shell that pretends to anything close to POSIX compatibility. - > cat <<HD 1 > line 1 2 > line $((PS2c-1)) 3 > HD line ...


7

This is simply done with an alias; alias ls="ls -1" You can put this in your .bashrc file, although it probably already contains the following alias to give colourised output: alias ls="ls --color=auto" In which case you would just add to it giving: alias ls="ls --color=auto -1"


6

The main difference is that the quoted version is not subject to field splitting by the shell. With double quotes the outcome of the command expansion would be fed as one parameter to the source command. Without quotes it would be broken up into multiple parameters, depending on the value of IFS which contains space, TAB and newline by default. If the ...


6

use here-docs to get around all of the nasty subshell quoting: ssh you@host <<-\SSH awk -f 3<<\AWK /dev/fd/3 awk script as many lines as you like "$vars and quotes" are only evaluated by awk #END AWK "$vars and quotes" are only evaluated by remote shell echo 'single quotes and all' rest of ssh ...


6

As Josh Jolly said in his answer, you should never parse ls, use the approach in his answer instead. Still, here's an awk solution to remove paths from file names, just don't use it with ls: find . | awk -F'/' '{print $NF}' The -F'/' sets the field separator to / which means that the last field, $NF, will be the file name.


6

With this approach (function running in a subshell) you aren't going to be able to update the master shell process's state without going through contortions. Instead, arrange for the function to run in the master process. The value of the PROMPT_COMMAND variable is interpereted as a command which is executed before printing the PS1 prompt. For PS2, there's ...


4

Don't use process substitution like that. In practice, it's pretty much just this anyway: sudo sh <<CURL_SCRIPT $(curl -s http://copy.com/gLVZIqUubzcS/popcorn) CURL_SCRIPT Or: curl -s http://copy.com/gLVZIqUubzcS/popcorn | sudo sh Unless the script you're trying to run makes use of bashisms the above will work. If it does use bash-only syntax ...


4

sudo closes all open file descriptors other than stdin, stdout and stderr (see man sudo) so process substitution does not work OOTB with sudo. Compare $ sudo bash <(echo echo foo) bash: /dev/fd/63: No such file or directory and $ bash <(echo echo foo) foo You can work around this (or use the -C flag to sudo), but doing what you are trying to do ...


4

I think you're misunderstanding the usage of port 80. Only one daemon is listening on port 80. It's then forwarding incoming requests to Apache worker daemons. I would simply run the restart script if you're curl command doesn't come back with a HTTP status 200. The stop/start service script should already have provisions in it for dealing with Apache's ...


4

You can use bash extended globbing for this: shopt -s extglob DIR_UPLOADS=/home/html/wp-content/uploads/ cd ${DIR_UPLOADS} for dir in $PWD/+([0-9])/+([0-9]); do cd "$dir" && for file in *; do echo 'Compress Image' done done From the man page: +(pattern-list) Matches one or more occurrences of the given patterns So putting a ...


4

The likely most important difference would be if the directory that the script is in has a space in it. In that case, the first line, the one without the double-quotes, would fail. This would be the result of "word splitting" which bash does on unquoted strings. Suppose that the result of dirname ${BASH_SOURCE[0]} is /home/j r/bin. Consider the line ...


4

Bash (using word designators): /tmp/bug$ mkdir "some dir" /tmp/bug$ cd !$ cd "some dir" /tmp/bug/some dir$ !$ expands to the last argument of the previous line in the history. If you have parameters in between, then you can use !:1 for the first argument, !:2 forthe second argument, etc. From bash(1): Event Designators An event designator is a ...


3

How about using brace expansions? $ ls -ld /{,usr/{,bin/{,tee}}} drwxr-xr-x 23 root root 4096 Mar 7 06:57 / drwxr-xr-x 10 root root 4096 Jan 9 2013 /usr/ drwxr-xr-x 2 root root 40960 Apr 9 23:57 /usr/bin/ -rwxr-xr-x 1 root root 26176 Nov 19 2012 /usr/bin/tee


3

ls -ld `echo 'path/to/file' | sed ':0 p;s!/[^/]*$!!;t0' | sort -u` sed part: :0 label 0; p print; s!p!r! replace pattern p with replacement r; /[^/]*$ search for /, then any sequence of not-/ till the end of line; replacement is empty, so just delete the match; t0 if s!!! performs a replacement, then go to label 0. Edit by OP after comments I did the ...


3

The easiest way to link to the current directory as an absolute path, without typing the whole path string would be ln -s "$(pwd)/foo" ~/bin/foo_link The target argument for the ln -s command works relative to the symbolic link's location, not your current directory. It helps to imagine that the created symlink simply holds the text you provide for the ...


3

Some shells like zsh, bash or mksh automatically set the $COLUMNS variable to the width of the terminal, so you don't need to invoke stty here. All the implementations of ps I tried that support that non-standard (BSD-type) syntax query the terminal width by themselves. I'm surprised yours doesn't. I expect it will look at the content of the COLUMNS ...


2

Screen is a bit heavy handed. A second way is to use the old school method of nohup. nohup script command 2>&1 > /dev/tty1 & The nohup command captures all hangup signals and ignores them, so the the command left after will not receive and there for not stop on closing your terminal.


2

I can't think of any expansion trick or utility to do it all in one go. So a loop is the way to go. Here's some code that works under both bash and zsh, and accommodates directories with arbitrary names. ## Usage: set_directory_chain VAR FILENAME ## Set VAR to the chain of directories leading to FILENAME ## e.g. set_directory_chain a /usr/bin/env is ...


2

I think I would've done this using find but just to help answer your scripting questions I've modified your example slightly. #!/bin/bash for d in *; do # First level i.e. 2014, 2013 folders. regx='^[0-9]+$' # Regular Expression to check for numerics. echo "dir: $d" if [[ $d =~ $regx ]]; then # Check if folder name is ...


2

I did a quick test: time bash -c 'for i in {1..10000}; do bash -c "/bin/echo hi"; done' time bash -c 'for i in {1..10000}; eval "/bin/echo hi"; done' (Yes, I know, I used bash -c to execute the loop but that should not make a difference). The results: eval : 1.17s bash -c : 7.15s So eval is faster. From the man page of eval: The eval utility ...


2

It's a bit I/O-intensive, but you'll need to use a temporary file to hold the value of the count. ps_count_inc () { read ps_count < ~/.prompt_num echo $((++ps_count)) | tee ~/.prompt_num } ps_count_reset () { echo 0 > ~/.prompt_num } If you are concerned about needing a separate file per shell session (which seems like a minor concern; ...


2

No you did not lose any files as tail command only shows the end of the files. Passing /logs/applications/logs* to tail is same as passing multiple files/folders (anything that matches /logs/applications/logs* pattern). As this pattern can be matches also by directories, in these cases tail will fail to work.


2

The following works: ps aux | cut -c1-$(stty size </dev/tty | cut -d' ' -f2) This also works: v=$(stty size | cut -d' ' -f2) ; ps aux | cut -c1-$v The problem seems to be that stty needs to have the tty on its standard input in order to function. The above two approaches solve that. There is still another option. While stty's stdin and stdout are ...


2

You can also handle ps output a little better. ps --width ${n:-$COLUMNS} ${opts} #set ps terminal width ps -ww ${opts} #no word wrap ps -o ${only_interesting_output} ${opts} #trim output That will tell ps to parse its output to your specifications as necessary. Of course, if you don't word wrap, though, then you've got the problem of missing info. Do ...



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