Archive

Posts Tagged ‘path’

JSON Path

May 20, 2017 1 comment

I wrote a command-line program that outputs the full path of every key / value in a JSON file.

Example

$ ./json_path.py sample.json
root.a => 1
root.b.c => 2
root.b.friends[0].best => Alice
root.b.friends[1].second => Bob
root.b.friends[2][0] => 5
root.b.friends[2][1] => 6
root.b.friends[2][2] => 7
root.b.friends[3][0].one => 1
root.b.friends[3][1].two => 2

More information at the project’s github page.

Advertisements
Categories: bash, python Tags: ,

the command “source” doesn’t exactly work the way you thought

November 22, 2014 1 comment

We know that “source” is a bash shell built-in command that executes the content of the file passed as argument in the current shell. It has a synonym: ‘.‘ (dot).

The classical use case is “source .bashrc” in your HOME directory. You do it when you modify your ~/.bashrc file and you want to activate the changes in the current terminal.

TIL something new. I had a discussion about it at reddit and the user geirha gave such a clear answer that I would quote him:

“The . (source is an alternative name for . in bash) command behaves more or less the same as when executing a command.

In POSIX sh, the following two will search for a file named foo in PATH (only).

    foo
    . foo

while the following two will specifically run and source, respectively, the file named foo in the current directory (only)

    ./foo
    . ./foo

Bash differs slightly (when not running in posix mode) in that when you give . or source an argument without any slash (/) characters (e.g. source foo), it searches through the PATH variable, like POSIX sh, but then also checks the current directory, if it was not found in PATH.” (end of quote)

Problem
Because of this I ran into a strange problem. I had a file called “.venv” that I wanted to source (source .venv) but I got some error. If I renamed the file, it worked well. But I wanted to call it “.venv”. What’s wrong?

Explanation
As explained above, it turned out that “source” started to look for “.venv” in the PATH first. Somehow it found a different file with the very same name and that caused the problem. When I renamed the file to “not_hidden” or “.jabba”, it worked.

Solution #1
The trivial way is to use “./” by telling source to take the argument from the current directory:

source ./.venv

However, in my entire life I thought that “source .bashrc” takes the file .bashrc from the current directory. It should, in my opinion :)

Solution #2
If you also think that “source” shouldn’t do anything with the PATH variable, there is a cure. This feature can be switched off. The command “shopt” is a builtin that allows you to change additional shell optional behavior.

The guilty option is this one:

sourcepath

    If set, the source builtin uses the value of PATH to find 
    the directory containing the file supplied as an argument. 
    This option is enabled by default.

Simply run “shopt” to see if “sourcepath” is on for you. You can switch it off easily:

shopt -u sourcepath

To make it permanent, add this line to the end of your ~/.bashrc.

After all this ado, I could finally write this:

. .venv

And this is the beauty of Linux. You learn something new every day :)

Links

Categories: bash Tags: , , , ,

Show the absolute path of a file

March 17, 2011 Leave a comment

When working in a terminal, a common task is to get the absolute path of a file. For instance, you want to open the given file with another (already running) application.

Old method:

Well, to get the absolute path of a file, I was doing the following:

C:\usr\local\lib\python2.6\dist-packages> ls -al
total 32
drwxrwsr-x  4 root staff 4096 2011-03-16 14:41 .
drwxrwsr-x  4 root staff 4096 2010-10-25 21:22 ..
drwx--S--- 10 root staff 4096 2010-09-29 09:30 pyglet
-rw-------  1 root staff 1039 2010-09-29 09:30 pyglet-1.1.4.egg-info
drwx--S---  2 root staff 4096 2011-03-16 14:41 termcolor-1.1.0.egg-info
-rw-r--r--  1 root staff 5044 2011-03-16 14:41 termcolor.py
-rw-------  1 root staff 3672 2011-03-16 14:41 termcolor.pyc
C:\usr\local\lib\python2.6\dist-packages> pwd
/usr/local/lib/python2.6/dist-packages
C:\usr\local\lib\python2.6\dist-packages>

First, find the file (termcolor.py in this example). Second, get the current working directory with the pwd command. Third, copy and paste the current working directory. Finally, copy and paste the filename. At each copy/paste, I had to switch between the terminal and the other application where I needed the absolute path. Too much work…

New method:

C:\usr\local\lib\python2.6\dist-packages> ls -al
total 32
drwxrwsr-x  4 root staff 4096 2011-03-16 14:41 .
drwxrwsr-x  4 root staff 4096 2010-10-25 21:22 ..
drwx--S--- 10 root staff 4096 2010-09-29 09:30 pyglet
-rw-------  1 root staff 1039 2010-09-29 09:30 pyglet-1.1.4.egg-info
drwx--S---  2 root staff 4096 2011-03-16 14:41 termcolor-1.1.0.egg-info
-rw-r--r--  1 root staff 5044 2011-03-16 14:41 termcolor.py
-rw-------  1 root staff 3672 2011-03-16 14:41 termcolor.pyc
C:\usr\local\lib\python2.6\dist-packages> sp termcolor.py
/usr/local/lib/python2.6/dist-packages/termcolor.py
C:\usr\local\lib\python2.6\dist-packages> sp termcolor.py | tocb
C:\usr\local\lib\python2.6\dist-packages>

The script “sp” (see below) takes one argument (a file name) and it prints the concatenation of the current directory and the file name, i.e. the absolute path of the file. Of course, you need to use the script in the directory where the given file is located. If no argument is given, it will print the current working directory.

If your goal is to paste the absolute path to somewhere else, you can copy the output of sp to the clipboard with tocb.

The script

The name of the script stands for “show path”.

#!/usr/bin/env python

# sp.py ("show path")

import os
import os.path
import sys

if len(sys.argv) == 1:
    print os.getcwd()
else:
    print os.path.join( os.getcwd(), sys.argv[1] )

Update (20110402)

The script is pushed to GitHub: https://github.com/jabbalaci/Bash-Utils.

Categories: bash, python Tags: , , , ,