LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-07-2020, 10:58 PM   #1
AlMeu
LQ Newbie
 
Registered: Nov 2019
Location: Undeva
Posts: 14

Rep: Reputation: Disabled
Reading a value from a ini, compare and execute


Hi guys

I play in Pocky version with some scripts and I get problem with a very simple structure of "if" to compare a numeric value and execute something and I can't figure out why doesn't want execute correct.

The diag variable takes values 0 or 1.
I have a "system.ini" file where is memorized this numeric value:
Code:
[version]
diag=1
a library file "common.sh" where are defined common variables:
Code:
ModDIAG=$(awk -F "=" '/diag/ {print $2}' $dir/COMUN/Info/system.ini)
and in other script "test.sh" I try use this variable for enable some code for debug:
Code:
source $dir/scripts/common.sh

echo  "ModDiag=$ModDIAG" > /dev/kmsg
if [[ "$ModDIAG" -eq 1 ]]
then
	echo  "This is a test" > /dev/kmsg
fi
echo  "End test" > /dev/kmsg
at the end, no mater what condition I put in if, I get always on screen:
Code:
ModDiag=1
End test
The reading value is correct but if condition for numeric value doesn't execute.
What I miss?

Last edited by AlMeu; 07-07-2020 at 11:02 PM.
 
Old 07-07-2020, 11:52 PM   #2
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,310
Blog Entries: 3

Rep: Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721
There probably shouldn't be quotes around a variable if it is to be treated like an integer.

You could try adding the following after the "source" line:

Code:
set -xv
That will show you what is actually in the variable and the exact line being parsed by the script.

However, there are perl and python modules for parsing INI files. If you're getting a more complex INI file to deal with, one of those might be worth looking at instead.

https://docs.python.org/3/library/configparser.html

https://metacpan.org/pod/Config::Any::INI

Last edited by Turbocapitalist; 07-07-2020 at 11:54 PM.
 
Old 07-08-2020, 02:14 AM   #3
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,670

Rep: Reputation: Disabled
Hmm,
Code:
$ bash -c '[[ "1" -eq 1 ]]&&echo yep||echo nay'
yep
OTOH, [[ ... ]] is not a POSIX-conform syntax, so if you have the #!/bin/sh shebang, and you /bin/sh is not Bash, then
Code:
$ dash -c '[[ 1 -eq 1 ]] 2>/dev/null&&echo yep||echo nay'
nay
 
Old 07-08-2020, 06:05 AM   #4
AlMeu
LQ Newbie
 
Registered: Nov 2019
Location: Undeva
Posts: 14

Original Poster
Rep: Reputation: Disabled
Angry

It's a bash code #!/bin/bash
It's seams to be obvious the code but is just jumping over and never execute what is inside:

Code:
#!/bin/bash

echo "ModDiag=$ModDIAG"
if [[ "$ModDIAG" -gt 0 ]]; then
 echo "Test"
fi
echo "......"
I tried also:
Code:
echo "ModDiag=$ModDIAG"
bash -c '[[ "$ModDIAG" -eq 1 ]]&&echo "yes"||echo "no"'
echo "......"

and I get always:
Code:
ModDiag=1
......
It's not the problem the reading ini file. The value get in echo ModDiag is correct.
Only the comparation seams is not executing at all, just jumping.

Last edited by AlMeu; 07-08-2020 at 06:07 AM.
 
Old 07-09-2020, 03:54 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,864
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
You might have some whitespace characters in your `system.ini` file (space, tab, carriage return etc)
Perhaps you should start it again from a working version (see the attached file).
Attached Files
File Type: txt trythis.txt (321 Bytes, 15 views)
 
Old 07-09-2020, 12:15 PM   #6
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,226

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
Can you use Python?

Code:
>>> import configparser
>>> parser = configparser.ConfigParser()
>>> parser.read_string('''[version])
... diag=1''')
>>> parser['version']['diag']
'1'
 
Old 07-09-2020, 01:02 PM   #7
Ser Olmy
Senior Member
 
Registered: Jan 2012
Distribution: Slackware
Posts: 3,341

Rep: Reputation: Disabled
Quote:
Originally Posted by AlMeu View Post
The reading value is correct but if condition for numeric value doesn't execute.
What I miss?
That's a very good question, because I just replicated your setup by pasting the code/data into the three files involved (common.sh, system.ini, and the main batch file), and it seems to work just fine.

Please run the main file with "bash -x <filename>" and post the results.
 
Old 07-09-2020, 01:19 PM   #8
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,226

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
If system.ini is literally the following:

Code:
[version]
diag=1
Code:
❯ tail -n 1 system.ini | cut -d = -f 2
1
 
Old 07-09-2020, 01:26 PM   #9
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,226

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
I'm not getting your results?

Code:
❯ cat common.sh
ModDIAG=$(awk -F "=" '/diag/ {print $2}' system.ini)

❯ cat test.sh
#!/usr/bin/env bash

source common.sh

echo  "ModDiag=$ModDIAG"
if [[ "$ModDIAG" -eq 1 ]]
then
	echo  "This is a test"
fi
echo  "End test"

❯ bash test.sh
ModDiag=1
This is a test
End test
When I tried it, it's working as expected?

I tried adding some trailing whitespace to system.ini and it didn't change anything?

Last edited by dugan; 07-09-2020 at 01:27 PM.
 
Old 07-11-2020, 07:58 PM   #10
Skaperen
Senior Member
 
Registered: May 2009
Location: center of singularity
Distribution: Xubuntu, Ubuntu, Slackware, Amazon Linux, OpenBSD, LFS (on Sparc_32 and i386)
Posts: 2,684
Blog Entries: 31

Rep: Reputation: 176Reputation: 176
for things like this, i find the python language easier to achieve success. it is worth learning. all the major distributions of Linux include python version 3.

Last edited by Skaperen; 07-11-2020 at 08:04 PM.
 
Old 07-14-2020, 10:04 AM   #11
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,226

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
The first thing I did when I saw this thread was do a search for command-line ini parsers, and I was surprised when I didn't find one.

I mean, three of the options listed here are fairly standardized, and any of them could have been used to write one in C/C++.

https://stackoverflow.com/q/147902/240515

Anyone in the mood to do this?
 
Old 07-14-2020, 11:08 AM   #12
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,670

Rep: Reputation: Disabled
Quote:
Originally Posted by dugan View Post
The first thing I did when I saw this thread was do a search for command-line ini parsers, and I was surprised when I didn't find one.
I did the same and found these two: crudini, confget.
 
1 members found this post helpful.
Old 07-15-2020, 10:29 AM   #13
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
Quote:
Originally Posted by dugan View Post
The first thing I did when I saw this thread was do a search for command-line ini parsers, and I was surprised when I didn't find one.

I mean, three of the options listed here are fairly standardized, and any of them could have been used to write one in C/C++.

https://stackoverflow.com/q/147902/240515

Anyone in the mood to do this?
Why not - since there is no specification I guess you get to make up the rules. This version limits line length, reads a file or stdin, accepts a key or section:key as argument and prints its findings to stdout. Probably not very useful and I have no intention of doing anything farther with it but it did use up some, otherwise valuable, time. :P

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LINE_BUFFER_SIZE 1025

void usage (char* app);
int get_section_key (char* arg, char** section, char** key);
int check_for_key (char* line, char* section);
int check_for_section (char* line);

int main (int argc, char** argv) {
	FILE* in;

	if (argc < 2) {
		usage (argv[0]);
		exit (EXIT_FAILURE);		
	}

	if (argc == 3) {
		in = fopen (argv[2], "r");
		if (in == NULL) {
			perror ("fopen");
			fprintf (stderr, "Unable to open %s for reading\n", argv[2]);
			usage (argv[0]);
			exit (EXIT_FAILURE);
		}
	} else {
		in = stdin;
	}

	char* section = NULL;
	char* key = NULL;

	int has_section = get_section_key (argv[1], &section, &key);

	int c = 0;
	char current_line[LINE_BUFFER_SIZE];
	char current_section[LINE_BUFFER_SIZE] = { 0 };
	
	int current_count = 0;
	int section_found = 0;

	while ((c = fgetc (in)) != EOF) {
		if (c == '\n') {
			if (current_count == 0) {
				continue;
			} 

			if (current_count == LINE_BUFFER_SIZE) {
				fprintf (stderr, "Maximum line length of %d exceeded\n", LINE_BUFFER_SIZE);
				exit (EXIT_FAILURE);	
			}

			current_line[current_count] = '\0';
			current_count = 0;			
			
			section_found = check_for_section (current_line);
			if (section_found) {
				strncpy (current_section, current_line + 1, strlen (current_line) - 2);
			} else {
				if (!has_section || (has_section && (strcmp (section, current_section) == 0))) {
					if (check_for_key (current_line, key)) {
						printf ("%s:%s\n", current_section, current_line);
					}
				} 

			}
		} else {
			current_line[current_count] = (char)c;
			++current_count;
		}
	}

	if (argc == 3) {
		fclose (in);
	} 

	if (!feof (in) && ferror (in)) {
		perror ("fgetc");
		exit (EXIT_FAILURE);
	}


	return EXIT_SUCCESS;
}


void usage (char* app) {
	printf ("usage: %s [section:]key [filename]\n", app);
}

int get_section_key (char* arg, char** section, char** key) {
	char* parg = arg;
	int has_section = 0;

	while (*parg != '\0') {
		if (*parg == ':') {
			has_section = 1;
			*parg = '\0';
			++parg;
			*key = parg;
			*section = arg;
			break;
		}
		
		++parg;	
	} 

	if (!has_section) {
		*key = arg;
	}

	return has_section;
}

int check_for_section (char* line) {
	int found = 0;
	int len = strlen (line);

	if (line[0] == '[' && line[len - 1] == ']') {
		found = 1;
	}

	return found;
}


int check_for_key (char* line, char* key) {
	char* pline = line;
	char* pkey = key;
	int found = 0;

	while (*pline != '\0') {
		if (*pline == '=') {
			found = 1;
			break;
		}
		
		if (*pkey == '\0') {
			break;
		}		
	
		if (*pline != *pkey) {
			break;
		}

		++pline;
		++pkey;
	}

	return found;
}
Code:
$ gcc -std=c11 -Wall ini_parser.c -o ini_parser
$ ./ini_parser
usage: ./ini_parser [section:]key [filename]
$ cat ./test.ini | ./ini_parser world
helo:world=true
names:world=earth
$ cat ./test.ini | ./ini_parser helo:world
helo:world=true
$ cat ./test.ini
[helo]
world=true
others=false
[names]
world=earth
moon=luna
 
  


Reply

Tags
ini



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[OpenStack/DevStack] Create the provider network - which .ini files are in use (ml2_conf.ini AND linuxbridge_agent.ini) czezz Linux - Virtualization and Cloud 3 08-02-2019 10:17 PM
strange value assignments variable = value, value?? ostrow30 Programming 2 07-24-2011 07:59 AM
[SOLVED] php.ini.rpmsave instead of php.ini ilvista Linux - Server 3 02-01-2011 04:39 PM
difference between value *value and value * value PoleStar Linux - Newbie 1 11-26-2010 03:37 PM
php.ini-dist to php.ini lord-fu Programming 10 05-02-2006 05:24 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:16 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration