Hot answers tagged

45

source or the equivalent but standard dot . do not execute the script, but read the commands from script file, then execute them, line by line, in current shell environment. There's nothing against the use of execution bit, because the shell only need read permission to read the content of file. The execution bit is only required when you run the script. ...


19

Instead of history, you can use fc, which allow you select range: fc -l 4 7


18

The executable bit (unlike the rest) on nonsetuid and nonsetguid files isn't much of a security mechanism. Anything you can read, you can run indirectly, and Linux will let you indirectly read anything you can run but not directly read (that should be enough to punch a hole in the concept of non-set(g)uid x-bit being a security measure). It's more of a ...


16

Bash is an interpreter; it accepts input and does whatever it wants to. It doesn't need to heed the executable bit. In fact, Bash is portable, and can run on operating systems and filesystems that don't have any concept of an executable bit. What does care about the executable bit is the operating system kernel. When the Linux kernel performs an exec, ...


14

The way you wrote your alias, the command you run would be expanded as pcmanfm 1>/dev/null 2>&1 & '/' This will run pcmanfm without any options as a background job and then try to run / as a command. You probably want a function instead of an alias explorer() { pcmanfm "$@" >/dev/null 2>&1 & }


11

You can trap the DEBUG signal: trap 'printf "\n"' DEBUG DEBUG trapped command printf "\n" will be run before the command is executed unlike PROMPT_COMMAND which will be run after the command is executed. You can add this to your ~/.bashrc to make it permanent. Example: $ abc No command 'abc' found, did you mean: .... $ trap 'printf "\n"' DEBUG $ abc ...


8

That's a good question! Unix uses the executable bit to distinguish between programs and data. The OS does not require the execution bit, since a sourced script is not passed to the OS for execution as a new process. But the shell treats a sourced script as a program, and will look in $PATH for the file you want to source. So, the shell itself could have ...


6

No. By the time a shebang comes into play, you have already lost. A shebang is applied when a process is exec()'d and typically that happens after forking, so you're already in a separate process. It's not the shell that reads the shebang, it's the kernel.


5

$$ is the process ID of the current shell instance. So in your case the number, 23019, is the PID of that instance of bash. The following should give you a better idea: ps -p $$


5

make test || true e.g. #!/bin/sh set -e echo hello make test || true echo done Will result in hello make: *** No rule to make target `test'. Stop. done In this case the failure was a missing rule (no Makefile :-)) but we can see the script continues.


5

You can use !!:* to refer to all the words but the zeroth of the last command line. !! refers to the previous command, : separates the event specification from the word designator, * refers to all the words but the zeroth. This is from the HISTORY EXPANSION section of bash(1). wieland@host in ~» cat foo | grep bar bar wieland@host in ~» tail -f !!:* tail -...


5

You can do this with an awk command most easily: your-command | awk -F\" -v OFS=. -v ORS=' ' '{print $2, $4, $6, $8}' To set it as a variable, use command substitution: myVariable="$(your-command | awk -F\" -v OFS=. -v ORS=' ' '{print $2, $4, $6, $8}')" -F sets the input field separator (which is by default any whitespace) to a custom value; in this ...


5

There must not be any spaces between a variable name and the equation mark. When there are spaces, the variable name is interpreted as a command, in this case the command host is run with parameters = and the host name.


4

If you must use history command, pipe it through sed or awk: history | sed -n '10,20p' history | awk 'NR >= 10 && NR <= 20' Otherwise cuonglm's answer is better option.


4

As far as the OS is concerned, a file containing shell script is just data. If you pass the name of such a data file to the source command or pass it on the command line to an invocation of the bash shell, all the OS sees is a string that happens to coincide with the name of a file containing data. How would the execute bit be at all relevant in that case?


4

Assuming there's a file called dates containing the list of dates, one per line (and nothing else), something like this might work to count the ones older than 14 days: $ date=$(date --date="14 days ago" +%Y%m%d) $ awk '($0 < "'$date'") {count += 1} END {print count}' < dates 20 (Given they are in yyyymmdd format, the comparison is easy.)


4

bash supports C-style for loops as follows: a=5 # example for ((i = 0; i < a; i++)); do for ((j = i; j < a; j++)); do echo "$i $j" done done See here for more: http://www.tldp.org/LDP/abs/html/loops1.html


4

The alias provides a literal expansion. So running explorer / maps to pcmanfm 1>/dev/null 2>&1 & / This runs pcmanfm in the background, immediately followed by / in the foreground.


3

The distinction is important because you may have a file of shell commands which is not useful as an executable, but only useful when sourced. For this file you can turn off the execute bit and then it will never be accessed unless explicitly in a source command. The reason for such a thing is to have side effects on the shell it is run from. For a ...


3

Add the following line to your ~/.inputrc file: set mark-symlinked-directories on See "Readline Init File Syntax" in the Bash Reference Manual for more on this topic.


3

Your second command works, the issue is you are using bash or whatever shell that put all pipelines components in a subshell. myresult2 is properly set but the variable is immediately out of scope unless you stay in the same subshell like here: curl -L 'https://archive.org/wayback/available?url=stackoverflow.com' \ 2>/dev/null | { myresult2=$(...


3

The wc (word-count) utility is able to count lines in a file: $ wc -l num.txt ... or rather, it counts the number of newlines in the file, which most of the time is the same thing (actually, on a Unix system, that is defined as the same thing). The manual (on Mac OS X) states: "Characters beyond the final <newline> character will not be ...


3

You were on the right track to use awk. You should write a script that reads your logs, and outputs with the fields separated with tabs¹. Then use the column command to re-align the columns: extract.awk²: BEGIN {OFS="\t"; print "Timestamp\tEmailTo:\tEmailFrom:\tIPAddress:\tErrorCodes:"} {print $1, $6, $7, $NF, $(NF-5)} Then run it with this command: awk ...


3

You can use history expansion $ echo test !#:^ echo test test test test $ echo a/b/test.py proj_copy/!#:^ echo a/b/test.py proj_copy/a/b/test.py a/b/test.py proj_copy/a/b/test.py !# The entire command line typed so far. :^ The first argument You could also use brace expansion $echo test{,} test test $echo {,proj_copy}/a/b/test.py /a/b/...


3

You can do it without the grep: df --output=target,size /mnt/xyz | awk ' NR==2 { print $2 } ' df accepts as argument the mount point; you can tell to awk too to print both the second line only (NR==2) , and the 2nd argument, $2. Or better yet, cut the target as you are not outputting it, and it becomes: df --output=size /mnt/xyz | awk ' NR==2 ' When I ...


3

Your command $ find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh has the effect that at most four copies of the someFunction.sh shell script will be started (-P 4) in parallel (new ones will be spawed as soon as the old ones are done), each one getting one filename as its argument (-n 1). This means that each invocation of your script will look ...


3

You should put your environment variables in ~/.profile. In this file you can also place environment variable assignments, since it gets executed automatically by the DisplayManager during the start-up process desktop session as well as by the login shell when one logs in from the textual console. — https://help.ubuntu.com/community/...


2

Use eval on your final line, and make sure the parent shell doesn't eat the $: #!/bin/bash export FOO=bar export BAR=baz eval "$@" run like so: wouter@gangtai:~$ ./foo.sh echo '$BAR' baz For more information, see help eval.


2

This is occurring because the output for v3.3.6 was going to stderr, not stdout. Apparently, prior to v3.4.0 the output from python --version is sent to stderr, whereas in v3.4.0 and later this output is sent to stdout. Redirection of both stdout and stderr to the output file works just fine: python --version >> $fname 2>&1



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