Difference b/w ls -la and ls -la > ls-1.txt - linux

If I do ls -la, I get results like
total 16
drwxr-xr-x 4 rockse staff 136 Apr 28 16:55 .
drwx------+ 23 rockse staff 782 Apr 28 16:48 ..
-rw-r--r-- 1 rockse staff 32 Apr 28 16:49 1.sh
-rw-r--r-- 1 rockse staff 215 Apr 28 17:01 ls-1.txt
But if I do ls -la > ls-1.txt, I get this
total 8
drwxr-xr-x 4 rockse staff 136 Apr 28 16:55 .
drwx------+ 23 rockse staff 782 Apr 28 16:48 ..
-rw-r--r-- 1 rockse staff 32 Apr 28 16:49 1.sh
-rw-r--r-- 1 rockse staff 0 Apr 28 17:06 ls-1.txt
I understand that a file is created and then ls -la is written to the same but why doesn't it capture the snapshot of ls -la before creating the file because we are just writing stdout to a file ?

The redirection is done by the shell, not the program you're running. The processing done by the shell to implement this is similar to this (simplified):
Fork a child process
Open the output file
Connect stdout to the output file stream
Execute the program
Step 2 creates the file, so it will be visible when the program runs in step 4.
If step 2 were done after step 4, it wouldn't be possible to change the program's stdout to point to it.

Related

.htaccess shows up | But It doesn't exist

/var/www/html/talent-media.com/public_html/help/scp/apps/.htaccess
shows up, but there is no .htaccess file as per
[root#0rcan0mic apps]# ls -al
total 12
drwxr-xr-x. 2 root root 4096 Apr 28 00:05 .
drwxr-xr-x. 6 root root 4096 Mar 20 01:11 ..
-rw-r--r--. 1 root root 1349 Mar 20 01:11 dispatcher.php
[root#0rcan0mic apps]# pwd
/var/www/html/talent-media.com/public_html/help/scp/apps
[root#0rcan0mic apps]#
Thoughts?

Using ls in Linux to show directories only

I'm getting myself familiar with Linux (Debian 9). However I managed to get myself confused with the ls command manual. I made up the following trivial setting for testing:
meouser:~/triv_dir$ ls -laR
.:
total 24
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:42 .
drwxr-xr-x 19 meouser meouser 4096 Mar 27 15:41 ..
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:55 a
drwxr-xr-x 2 meouser meouser 4096 Mar 27 15:42 b
-rw-r--r-- 1 meouser meouser 6 Mar 27 15:44 c
-rw-r--r-- 1 meouser meouser 6 Mar 27 15:44 d
./a:
total 24
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:55 .
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:42 ..
-rw-r--r-- 1 meouser meouser 4 Mar 27 15:50 aa
-rw-r--r-- 1 meouser meouser 4 Mar 27 15:50 ab
drwxr-xr-x 2 meouser meouser 4096 Mar 27 15:55 a_sub_1
drwxr-xr-x 2 meouser meouser 4096 Mar 27 15:55 a_sub_2
./a/a_sub_1:
total 12
drwxr-xr-x 2 meouser meouser 4096 Mar 27 15:55 .
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:55 ..
-rw-r--r-- 1 meouser meouser 4 Mar 27 15:55 aaa
./a/a_sub_2:
total 8
drwxr-xr-x 2 meouser meouser 4096 Mar 27 15:55 .
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:55 ..
./b:
total 16
drwxr-xr-x 2 meouser meouser 4096 Mar 27 15:42 .
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:42 ..
-rw-r--r-- 1 meouser meouser 4 Mar 27 15:50 ba
-rw-r--r-- 1 meouser meouser 4 Mar 27 15:50 bb
I would like to see all the directory names and their subdirectories, but not the filenames. That is, I want something like ls --insert-options-here so that the output is this subset from above:
.:
total 24
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:42 .
drwxr-xr-x 19 meouser meouser 4096 Mar 27 15:41 ..
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:55 a
drwxr-xr-x 2 meouser meouser 4096 Mar 27 15:42 b
./a:
total 24
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:55 .
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:42 ..
drwxr-xr-x 2 meouser meouser 4096 Mar 27 15:55 a_sub_1
drwxr-xr-x 2 meouser meouser 4096 Mar 27 15:55 a_sub_2
According to ls manual that should be achieved by ls -ldR.
meouser:~/triv_dir$ man ls
-a, --all
do not ignore entries starting with .
-d, --directory
list directories themselves, not their contents
-l use a long listing format
-R, --recursive
list subdirectories recursively
But this is what happens instead: only the '.' is shown.
meouser:~/triv_dir$ ls -ldR
drwxr-xr-x 4 meouser meouser 4096 Mar 27 15:42 .
What am I missing from the manual?
I noticed from https://stackoverflow.com/a/29277454/11199684 that this can be achieved by
find . -maxdepth 2 -type d -print
which is impressive but it gives less information than the ls output above. Besides, I might not know beforehand the correct maxdepth? And above all, for future needs I'm actually interested in teaching myself from the manuals. Advice are appreciated.
The -d option apply to [FILE] given as input, in your case, as none are given, you fall back to the default one : the current directory. The recursivity doesn't apply as no directory are returned.
To get the same output as ls with the find command, you can combine them :
find . -type d -exec ls -ld {} \;
in some way you could use the grep tool to filter the results:
ll -A | grep ^d
if you want to use it programatically, in a bash script you can have only the dir names (but find might be better for that):
ll -A | grep / | awk '{print $9}'

How to attach to ghost screen session?

I've got a screen session running for the user heechan on my linux server:
heechan#vps3712:~$ ls -laR /var/run/screen/
/var/run/screen/:
total 0
drwxrwxr-x 5 root utmp 100 Aug 31 08:22 .
drwxr-xr-x 18 root root 640 Sep 18 05:24 ..
drwx------ 2 grt grt 60 Aug 27 04:03 S-grt
drwx------ 2 heechan heechan 40 Sep 1 09:44 S-heechan # <== THIS ONE
/var/run/screen/S-heechan:
total 0
drwx------ 2 heechan heechan 40 Sep 1 09:44 .
drwxrwxr-x 5 root utmp 100 Aug 31 08:22 ..
But when I do screen -ls I don't see the session:
heechan#vps3712:~$ screen -ls
No Sockets found in /var/run/screen/S-heechan.
heechan#vps3712:~$ screen -r
There is no screen to be resumed.
heechan#vps3712:~$
Where is this session and how I I resume it?
As you can see, /var/run/screen/S-heechan is empty, so there is no socket file inside.
Your screen is terminated. Perhaps you forgot to detach and exited instead? (To detach, use ctrl+a d )

Formatting ls output without tab using awk?

My question may seem fairly simple, I'm a beginner at bash scripting still, but I'm trying to format my ls output without using a tab when I print with awk.
Here is my current command that I'm running:
ls -al | sed 1d | awk '{print $1" ",$6" ", $7"\t", $9}'
and it prints out the following
drwx------ Feb 13 .
drwxr-xr-x Feb 5 ..
-rw-r--r-- Jan 21 .alias
-rw-r--r-- Feb 13 .bash_history
-rw-r--r-- Jan 29 .bash_profile
-rw-r--r-- Jan 21 .bash_profile~
-rw-r--r-- Feb 13 .bashrc
-rw-r--r-- Jan 21 .bashrc~
drwxr-xr-x Jan 3 csc135
drwxr-xr-x Aug 13 csc136
drwxr-xr-x Feb 9 csc235
drwxr-xr-x Oct 19 csc237
drwxr-xr-x Feb 18 csc310
drwxr-xr-x Feb 6 csc325
I have also attempted using a space:
ls -al | sed 1d | awk '{print $1" ",$6" ", $7" ", $9}'
which prints the following (quite bothersome):
drwx------ Feb 13 .
drwxr-xr-x Feb 5 ..
-rw-r--r-- Jan 21 .alias
-rw-r--r-- Feb 13 .bash_history
-rw-r--r-- Jan 29 .bash_profile
-rw-r--r-- Jan 21 .bash_profile~
-rw-r--r-- Feb 13 .bashrc
-rw-r--r-- Jan 21 .bashrc~
drwxr-xr-x Jan 3 csc135
drwxr-xr-x Aug 13 csc136
drwxr-xr-x Feb 9 csc235
drwxr-xr-x Oct 19 csc237
drwxr-xr-x Feb 18 csc310
drwxr-xr-x Feb 6 csc325
Is there any way to make it nicer looking like this?
drwx------ Feb 13 .
drwxr-xr-x Feb 5 ..
-rw-r--r-- Jan 21 .alias
-rw-r--r-- Feb 13 .bash_history
-rw-r--r-- Jan 29 .bash_profile
-rw-r--r-- Jan 21 .bash_profile~
-rw-r--r-- Feb 13 .bashrc
-rw-r--r-- Jan 21 .bashrc~
drwxr-xr-x Jan 3 csc135
drwxr-xr-x Aug 13 csc136
drwxr-xr-x Feb 9 csc235
drwxr-xr-x Oct 19 csc237
drwxr-xr-x Feb 18 csc310
drwxr-xr-x Feb 6 csc325
One automatic option that comes to mind is column:
$ ls -al | sed 1d | awk '{print $1,$6,$7,$9}' | column -t
drwxr-xr-x+ Feb 3 .
drwxrwxrwt+ Oct 9 ..
-rw------- Feb 12 .bash_history
-rwxr-xr-x Oct 9 .bash_profile
-rwxr-xr-x Feb 3 .bashrc
drwx------+ Feb 2 .cache
-rwxr-xr-x Oct 9 .inputrc
-rwxr-xr-x Feb 14 .mkshrc
-rwxr-xr-x Oct 9 .profile
drwxrwx---+ Dec 13 .ssh
Note the -t flag used for column:
-t, --table
Determine the number of columns the input contains and create
a table. Columns are delimited with whitespace, by default,
or with the characters supplied using the --output-separator
option. Table output is useful for pretty-printing.
Another way would be to used fixed lengths:
$ ls -al | sed 1d | awk '{printf "%-12s %-3s %-2s %s\n", $1,$6,$7,$9}'
drwxr-xr-x+ Feb 3 .
drwxrwxrwt+ Oct 9 ..
-rw------- Feb 12 .bash_history
-rwxr-xr-x Oct 9 .bash_profile
-rwxr-xr-x Feb 3 .bashrc
drwx------+ Feb 2 .cache
-rwxr-xr-x Oct 9 .inputrc
-rwxr-xr-x Feb 14 .mkshrc
-rwxr-xr-x Oct 9 .profile
drwxrwx---+ Dec 13 .ssh
There is another example of this in the GNU Awk User's guide.
ls -al|awk 'NR>1{print $1,$6,$7,$9}'|column -t
you don't need to use sed to delete the first line. Awk can do this if NR>1 print
You can avoid all unnecessary pipes by using features of awk.
ls -al | awk -v OFS="\t" 'NR>1 { print $1, $6, $7, $9 }'
Use NR>1 to get rid of the unnecessary sed to delete the first row.
Use OFS variable to set the output field separator to tab there by removing the need for column.

Quit hidden attribute to many files in a directory once in UNIX

Hello Everybody there.
I wanna know if there is a command of set of commands (maybe a pipeline set) which can be used to change the hidden attribute of many files stored in a particular directory, with the same name.
ie.
ls -la inside torrents/music/david_guetta_greatest_hits shows the next files:
drwxrwxrwx 20 crsuarez staff 680 Apr 9 19:25 .
drwxrwxrwx 20 crsuarez staff 680 Apr 9 19:11 ..
-rw-r--r-- 1 crsuarez staff 6894561 Apr 9 19:16 .I'm Famous.wma
-rw-r--r-- 1 crsuarez staff 7543777 Apr 9 19:16 .Gettin Over.wma
-rw-r--r-- 1 crsuarez staff 6378465 Apr 9 19:16 .I Gotta Feeling.wma
-rw-r--r-- 1 crsuarez staff 7245793 Apr 9 19:16 .In love with myself.wma
-rw-r--r-- 1 crsuarez staff 7060449 Apr 9 19:16 .It's the Way You Love Me.wma
-rw-r--r-- 1 crsuarez staff 7737313 Apr 9 19:16 .Love Don't Let Me Go.wma
-rw-r--r-- 1 crsuarez staff 7737313 Apr 9 19:16 .Love is Gone.wma
-rw-r--r-- 1 crsuarez staff 6628321 Apr 9 19:16 .Memories.wma
-rw-r--r-- 1 crsuarez staff 7525345 Apr 9 19:16 .Money.wma
-rw-r--r-- 1 crsuarez staff 7806945 Apr 9 19:16 .One Love.wma
-rw-r--r-- 1 crsuarez staff 7192545 Apr 9 19:16 .Sexy Bitch.wma
-rw-r--r-- 1 crsuarez staff 6954977 Apr 9 19:16 .Stay.wma
-rw-r--r-- 1 crsuarez staff 8025057 Apr 9 19:16 .The World is Mine.wma
-rw-r--r-- 1 crsuarez staff 7769057 Apr 9 19:16 .TitaniuM.wma
-rw-r--r-- 1 crsuarez staff 6693857 Apr 9 19:16 .Turn ME ON.wma
-rw-r--r-- 1 crsuarez staff 7215073 Apr 9 19:16 .When Love Takes Over.wma
-rw-r--r-- 1 crsuarez staff 8182753 Apr 9 19:16 .Without YoU.wma
I wanna unhide all of this files with a single set of commands (I don't care if I have to use pipeline), instead of use mv .hidden_file_name not_hidden_file_name.
The solution must be OSX Complain. ;)
Something like this
for origname in .[0-9A-Za-z]*
do
if [ -f "${origname}" ]; then
# compute your newname how you want it
mv "${origname}" "${newname}
fi
done
You'll have to decide what you want your new names to be - you'll strip off the leading dot '.' but doing only what will probably collide with an existing .wma file with the same name, so maybe also append .tmp -- like:
.One Love.wma --becomes--> One Love.wma.tmp
Use prename (rename on Debian-derived systems).
prename 's/^.//' .*.wma

Resources