aboutsummaryrefslogtreecommitdiff
path: root/doc/functions.txt
blob: 0f8cd609aac55925ab4757a70d58102201f3cc76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
FUNCTIONS

This is a document for example functions to ensure portability
across different systems. These are mere examples as we currently
depend on non POSIX utilities on packages. These dependencies will
be removed as we go forward.

I don't want to turn the functions in here into a library because
these are really simple, and I believe that the build scripts sho-
uld be self-contained. What's the point of creating portable func-
tions if the functions themselves depend on a library file to be
installed on a system?

These obviously have their own limitations, but not every limitation
has to be solved in a single function. Use your imagination, non-
standard flags/commands may save you some keypresses, but they are
not standard, because you can already do these with your brain and
a few more keypresses.

SED -i
------

The -i function isn't portable across systems, and isn't defined
by POSIX. But it isn't too valuable as it can be replaced with a
simple function. I present you sed_i. This function only depends
on the fact that the file name is the last argument.


    sed_i() {
        # This makes sure that we store the last argument on
        # a file variable.
        for file; do :; done

        # Run the arguments against sed, and redirect output
        # to a temporary file simply named '_'.
        sed "$@" > _
        # Instead of moving we cat into the file. This way we
        # do not have to worry about preserving permissions of
        # the file
        cat _ > "$file"; rm -f _
    }

In build scripts with multiple 'sed -i' usage, such a function
can be defined for and used. If only it is used a single time,
defining such a function is quite unnecessary. In such a case
prefer doing it manually. Assume the file is named 'file.h' and
we are calling 's/this/that/g'.


    sed 's/this/that/g' file.h >_
    cat _ > file.h; rm -f _


INSTALL -D,-t
-------------

'install' does not have a standard. Options such as '-D' and '-t',
even though they are the most used, do not exist on every impleme-
ntation. Avoid using these flags where possible. You can prefer us-
ing functions such as these. The first function is similar to '-t'
flag, where you can install multiple files to a given target. The
second function is similar to the usage without the '-t' flag, a
single file where it will be named as the argument.


    kinstall_t() {
         # usage: kinstall_t 755 /usr/bin file1 file2 file3
         mod=$1 dir=$2; mkdir -p "$dir"
         shift 2
         for file; do
             ! [ -d "$dir/$file" ] || {
                 printf '%s\n' "Error: $dir/$file is a directory >&2"
                 return 1
             }
             cp "$file" "$dir"
             chmod "$mod" "$dir/$file"
         done
    }


    kinstall() {
        # usage: kinstall 755 /usr/bin/file filename
        ! [ -d "$2" ] || {
            printf '%s\n' "Error: $target is a directory" >&2
            return 1
        }
        mkdir -p "${2%/*}"; cp "$3" "$2"
        chmod "$1" "$2"
    }