Tag Info

New answers tagged

2

The following works, but feels a bit kludgy (I'm hoping for a more clever answer): PROMPT_COMMAND='at_prompt=t' trap ' [ -z "${at_prompt+set}" ] || printf %s\\n "most recent history line: $(history 1)" >&2 unset at_prompt ' DEBUG


-1

Just answering my own question, in case someone else run into the same issue. You can either assign the PS1 variable in /etc/bashrc for all the users or comment out and use /.bash_profile for an individual account. In my case /.bash_profile was already setup and all I've to do was to disable PS1 in /etc/bashrc. Refer to the following screenshot. After the ...


0

sudo is a command to gain administrative rights temporarily. The error you get tells you that the program is not installed. You can gain administrative rights by switching to the root account. $ su root However, you need to know the password for the root account. If you don't know it you should see with someone who knows.


0

It looks to me like both files are already sorted on the first field. If so: join file1 file2 is best, by about as far as your files are large.


0

In zsh: als() { until [[ $1 = [/.] ]] {argv[1,0]=$1:h;}; ls -ld -- "$@" } POSIXly: als() ( while :; do case $1 in [./]) exec ls -ld -- "$@" esac set -- "$(dirname -- "$1")" "$@" done )


1

You can use awk: $ awk 'FNR==NR{a[$1];next}($1 in a){print}' file2 file1 A0001 C001 A0024 C234 B1542 C231


4

This should do the job: grep -Ff File2 File1 The -f File2 reads the patterns from File2 and the -F treats the patterns as fixed strings (ie no regexes used).


0

In order to print the input after the corresponding prompt, you need to know when the program is waiting for input. There's no way to tell from observing the running program: you can't distinguish a program that's waiting for input on stdin from a program that's waiting for something else (network, disk, computation, …). So the process to obtain a ...


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 ...


0

How about: $ cd /Users/niels/something $ ln -s ./foo ~/bin/foo_link


0

You can rebind the number keys for vi mode so they don't trigger the arg: N repetition. Try inserting the following in your ~/.bashrc (or you can test it in an active terminal first): bind -m vi 3:self-insert Then try hitting Escape and typing 3. You should get the number 3 printed. However, this is probably not a good behaviour, since you probably don't ...


1

The offending code is in: lib/readline/misc.c Removing lines 109 and 241 will remove the message.


5

In your case it printed previous backgrounded job result [xxx@host]$ /usr/bin/echo test>/dev/null & <Enter> [1] 4559 [xxx@host]$ <Enter> [1]+ Done /usr/bin/echo test > /dev/null


12

It will do nothing as far as I know. The ¬ will just be treated as an argument to the command: $ ls ¬ ls: cannot access ¬: No such file or directory


0

Add the line set -x in your program file. Example: #!/bin/bash set -x #echo on ls $PWD This expands all variables and prints the full commands before output of the command. output: + ls /home/user/ file1.txt file2.txt Check this answer from Stackoverflow for more similar flags for the set command.


1

When you're in command mode in vi (the the actual editor or the Bash mode), pressing digits inputs an argument (hence "arg") that is usually used to set the number of repetitions to perform the following command. To avoid that, you should be in input mode (by pressing i for example) before pressing digits. Demonstration: If you're not in vi mode, you can ...


5

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 ...


6

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

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. ...


1

You can not use a shell variable this way and you already understand why. A subshell inherits variables exactly the same way a process inherits its environment: any changes made apply only to it and its children and not to any ancestor process. As per other answers the easiest thing to do is stash that data in a file. echo $count > file ...


0

For reference, here’s my solution using temporary files, which are unique per shell process, and deleted as soon as possible (to avoid clutter, as alluded to in the question): # Yes, I actually need this to work across my systems. :-/ _mktemp() { local tmpfile="${TMPDIR-/tmp}/psfile-$$.XXX" local bin="$(command -v mktemp || echo echo)" local ...


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; ...


7

How about (cd lib && echo *.jar), assuming that you don't have whitespace or special characters in the file names. Parent script never changes directory.


5

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 ...


-1

An alternative way solve your query is to list all the files using ls -R. Combine the output of ls command with grep to list only .jar files. You can use following command to do the same for your query: ls -R lib | grep jar| grep -v jar*


5

With GNU find there is no need to run basename for every single file, this will be much faster (especially if there is a lot of files): find lib -name '*.jar' -printf '%P\n'


0

find is probably the way to go, but if you really, really do (you don't) want to strip off lib/ from ls -1, you can use sed: $ ls -1 lib/*.jar | sed 's#^lib/##' mylib_1.jar mylib_2.jar


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.


14

Instead of parsing ls you should use find instead. Then you can also execute basename on each file to strip the leading directories: find lib/ -name '*.jar' -exec basename {} \;


1

You mention you don't like tar --list because it's slow. I'm guessing this is because it's a large tarball, and it has to re-scan the whole thing. If this is indeed the case, you can get better performance out of this by scanning as it's being created: tar -c /input/directory | tee output.tar | tar -t > filelist.txt This uses tee to split the resulting ...


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 ...


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.


1

You could append each file to the tar file: for f in file ...; do echo "$f" tar rf result.tar $f done


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 ...


2

Linux (and no acl support): namei -l /foo/bar/baz


1

The problem is you want php to read input from a file descriptor, but you force it to read like regular file. First, try this: $ echo <(ls) /dev/fd/63 then you can process ls output by reading /dev/fd/63. The process substitution will return the file descriptor, which is use by other command to reading its output. In your case, you use ...


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 ...


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


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"


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

Spawn your script within a screen session. Redirect output to TTY as you proposed. Detach from the screen session and close the terminal. No SIGHUP will be sent so the script should continue to run.


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 ...


1

Referring again to the bash manual page: When using the -F or -C options, the various shell variables set by the programmable completion facilities, while available, will not have useful values. I assume this is the "unexpected behaviour" it's referring to. The lack of $COMP_WORDS and $COMP_CWORD in the subshell created by compgen mean that ...


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 ...


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 ...


0

If you don't want to loop through each entry of the second array for each value in the first, then you'll need to use an associative array. In awk you could do this: $ a=(a b c d); $ b=(a h c d l k); $ awk 'BEGIN{RS = FS} NR == FNR {a[$1] = 1; next} $1 in a' \ <(echo "${a[*]}") <(echo "${b[*]}") a c d Pure bash would look something like this ...


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 ...


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 ...


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 ...



Top 50 recent answers are included