Giter Site home page Giter Site logo

bashport's Introduction

Automatic version updates

GNU Bash

Bash is the GNU Project's shell*the Bourne Again SHell. This is an sh-compatible shell that incorporates useful features from the Korn shell (ksh) and the C shell (csh). It is intended to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard. It offers functional improvements over sh for both programming and interactive use. In addition, most sh scripts can be run by Bash without modification.

The improvements offered by Bash include:

command-line editing, unlimited size command history, job control, shell functions and aliases, indexed arrays of unlimited size, integer arithmetic in any base from two to sixty-four.

For more info please visit: https://www.gnu.org/software/bash/

bashport's People

Contributors

igortodorovskiibm avatar mikefultondev avatar v1gnesh avatar harithaibm avatar

Stargazers

 avatar Sean Kurtz avatar Clayton avatar TheBigD avatar  avatar Mike Großmann avatar  avatar

Watchers

James Cloos avatar  avatar  avatar  avatar

bashport's Issues

read.tests : failure with exec to a named pipe

The following sequence fails and then causes follow-on problems:

cd /tmp
rm -f a.pipe
mkfifo a.pipe
exec 9<> a.pipe

The 'exec' fails with:

bash: a.pipe: EDC5121I Invalid argument.

but should work.

A question about bash pipe(|)

I have an input file which is untagged and its content is ascii characters "abc".

$ echo abc >input
$ chtag -r input
$ chtag -p input
 - untagged    T=off input

And I have a Go program named main which reads data from stdin and prints the data in hex.
$ cat input | main
input is: 2fefbfbdc48e

I expected got "6162630a" which is "abc\n" in hex. It seems bash does a conversation from 819 to 1047. On my test system, _BPXK_AUTOCVT is set to "On". I am confused about the behavior. Any thought?
If the input file is tagged with 819 I got the expected output.
$ chtag -p input
6162630a

printf.tests fails

it appears that the .right file is out of date with the .tests file. In particular printf1.sub has a commented out line:

printf -v vv -- "--%b--\n" '\n\081'

that seems to be the missing output from the test suite (this might be because it looks to highlight an error in bash)

guidance on shells

On the Guild call (25/01) there was discussion on not making bash your default shell on z/OS - so rather having a simple .profile which switches to bash.

Wait command different behavior in bash

On running texinfo port test cases, malformed-split.sh test cases was hanging
On further analysis, found that this happens when wait is called on a PID.
Shell script was being used to run the scripts. On changing this to bash, it worked fine without hanging.

Need analysis to see why is this behavior different with bash?

awk issue under zot bash

This issue does not exist when using the Rocket port of bash:

image

This is the code that fails with the zot bash:

image

intl.tests: Length of UTF8 string is wrong

The sequence:

LC_ALL=en_US.UTF-8
LANG=en_US.UTF-8
var='абвгдежзиклмноп '
echo -"$var"- ${#var}

should print out:

-абвгдежзиклмноп - 16

but instead prints out:

-абвгдежзиклмноп - 31

ctrl+arrow isn't handled

I like to use the key combinations of ctrl+left arrow and ctrl+right arrow in bash to move the cursor between words. This has never worked on the z/OS bash ports, and does not work on the zOpen one either. It sure would be nice if this key combo worked properly.

Instead of moving the cursor, they key combos just print the below "garbage" characters. 5C and 5D are for left and right. 5A and 5B are for up and down.

angio@pkstnp8 ~> afdsads  afdssfdsfa;5D;5D;5C;5C;5A;5B;5D;5D;5D 

bash raises protection exception in Jenkins groovy environment

Typically looks like this (this one is from curl build: https://128.168.139.253:8443/job/Port-Build/1036/console)

CEE3204S The system detected a protection exception (System Completion Code=0C4).
         From compile unit zopen-ci1:./sig.c at entry point reset_terminating_signals at statement 363 at compile unit offset +00000000265C6580 at entry offset +0000000000000128 at address 00000000265C6580.
./configure: line 48253: 33554585 SIGSEGV                 cat >> $CONFIG_STATUS <<_ACEOF

Also libxml2 build: https://128.168.139.253:8443/job/Port-Build/1046/console

CEE3204S The system detected a protection exception (System Completion Code=0C4).
         From compile unit zopen-ci1:./sig.c at entry point reset_terminating_signals at statement 363 at compile unit offset +00000000265C6580 at entry offset +0000000000000128 at address 00000000265C6580.
./configure: line 17858: 16778047 SIGSEGV                 cat >> $CONFIG_STATUS <<_ACEOF

redir.tests: unable to set ulimit to required value (256)

The system I am testing on does not let me set the ulimit -n 256 but instead restricts me to ulimit -n 128 which requires the redir.right file to need to be updated. Need to see if this is a problem on other machines in which case we should request it be reduced, or alternately see if ZOSCAN2B can have it's ulimit -n increased.

posixexp.tests fails

Difference is in 'nl' vs 'lf':

For example, tracing test 37:

037: IFS = sp  ht  lf: unset -v foo; set -- ${foo=$*}
+ printf %s $'\001\002\003\177/\001\002\003\177'
+ trim_od
+ od -t a
+ sed -n '1 { s/^0*[[:blank:]]*//; s/[[:blank:]]*$//; p; }'
soh stx etx del   / soh stx etx del
+ for testcmd in 'unset -v foo; set -- ${foo=$*}' 'unset -v foo; set -- ${foo="$*"}' 'unset -v foo; set -- "${foo=$*}"' 'foo=; set -- ${foo:=$*}' 'foo=; set -- ${foo:="$*"}' 'foo=; set -- "${foo:=$*}"' 'unset -v foo; set -- ${foo=$@}' 'unset -v foo; set -- ${foo="$@"}' 'unset -v foo; set -- "${foo=$@}"' 'foo=; set -- ${foo:=$@}' 'foo=; set -- ${foo:="$@"}' 'foo=; set -- "${foo:=$@}"'
+ doTest 'unset -v foo; set -- ${foo="$*"}'
+ set -- $'\001\002\003\177'
+ eval 'unset -v foo; set -- ${foo="$*"}'
++ unset -v foo
++ set -- $'\001\002\003\177'
+ case ${IFS+s}${IFS:+n} in
++ printf %s '
'
++ trim_od
++ od -t a
++ sed -n '1 { s/^0*[[:blank:]]*//; s/[[:blank:]]*$//; p; }'
+ i='sp  ht  lf'
+ printf '\n%03d: IFS = %s: %s\n' 38 'sp  ht  lf' 'unset -v foo; set -- ${foo="$*"}'

performance issues

Good afternoon everyone,

First of all, I would like to thank you for putting so much time and effort into porting these very important tools.

I have noticed that there are massive differences in the execution time of shell scripts.
When I use bash instead of the default shell, execution is factors slower.

While I was researching, I found the following link.

I then simplified the test script a little and took some measurements of running times.
I am attaching my results to this issue here.

I realise that there are more important issues than performance at the moment,
but I'd like to put it in writing anyway.

Thanks and best regards
Mike


The Script

#!/bin/sh
count=1
while [ ${count} -le 500 ]
do
        out=`echo "Some test data" | cut -c1`
        count=$((count+1))
done

Results

using sh

MIKEG1@prod:~/perftest$ time ./test.sh

real    0m20,118s
user    0m3,791s
sys     0m1,264s
MIKEG1@prod:~/perftest$ time ./test.sh

real    0m14,980s
user    0m3,745s
sys     0m1,248s
MIKEG1@prod:~/perftest$ time ./test.sh

real    0m16,423s
user    0m3,739s
sys     0m1,246s
MIKEG1@prod:~/perftest$ time ./test.sh

real    0m16,667s
user    0m3,726s
sys     0m1,242s
MIKEG1@prod:~/perftest$ time ./test.sh

real    0m16,431s
user    0m3,758s
sys     0m1,253s

using bash v4 (rocket)

MIKEG1@prod:~/perftest$ time ./test.sh

real    1m15,267s
user    0m25,929s
sys     0m8,643s
MIKEG1@prod:~/perftest$ time ./test.sh

real    1m15,796s
user    0m25,838s
sys     0m8,613s
MIKEG1@prod:~/perftest$ time ./test.sh

real    1m8,562s
user    0m25,833s
sys     0m8,611s
MIKEG1@prod:~/perftest$ time ./test.sh

real    1m13,640s
user    0m25,913s
sys     0m8,638s
MIKEG1@prod:~/perftest$ time ./test.sh

real    1m8,053s
user    0m25,803s
sys     0m8,601s

using bash v5 (ZOSOpenTools)

MIKEG1@prod:~/perftest$ time ./test.sh

real    1m40,283s
user    0m42,381s
sys     0m14,127s
MIKEG1@prod:~/perftest$ time ./test.sh

real    1m39,797s
user    0m42,342s
sys     0m14,114s
MIKEG1@prod:~/perftest$ time ./test.sh

real    1m50,684s
user    0m42,598s
sys     0m14,199s
MIKEG1@prod:~/perftest$ time ./test.sh

real    1m44,472s
user    0m42,158s
sys     0m14,053s
MIKEG1@prod:~/perftest$ time ./test.sh

real    1m37,375s
user    0m42,034s
sys     0m14,011s

bash "type ping" is not able to point to external link ping command.

When i run command "type ping", I get o/p as "bash: type: ping: not found". But, i see ping is present under /bin/. When i run, ls -l /bin/ping , i get o/p as: erwxrwxrwx 1 BPXROOT 1 5 Apr 22 2020 /bin/ping -> OPING

Also, analysis and inputs from uss tools teams is:
stat() fails for an external link. bash checks the path to a command before it tries to exec it to make sure it is executable, using stat(). bash would have to be modified to look for the specific reason code from stat() and ignore it to get it to follow external links.

More info about this issue is in thread
"https://ibm-systems-z.slack.com/archives/C493603M1/p1678371986562979"

vredir.tests : wrong error message when setting ulimit under active descriptor

When invoking the sequence:

unset v
exec {v}</dev/null
if (( v >= 10 )); then echo ok 1; else echo bad 1; fi
exec {v}<&-
ulimit -n 6

the output should be:

ok 1
failed to close file descriptor 11: bad file descriptor

but instead it is:

ok 1
bash: ulimit: open files: cannot modify limit: EDC5121I Invalid argument.

netstat not found from the bash shell

Is this expected running bash? Does bash honor _BPX_SHAREAS=YES ?

bash-5.2$ type netstat
bash: type: netstat: not found

bash-5.2$ whence netstat
bash: whence: command not found

bash-5.2$ which netstat
bash: which: command not found

bash-5.2$ netstat
bash: netstat: command not found

bash-5.2$ type onetstat
onetstat is hashed (/bin/onetstat)

links in /bin
bash-5.2$ cd /bin
erwxrwxrwx 1 BPXROOT 10 8 Oct 12 2021 netstat -> ONETSTAT
lrwxrwxrwx 1 BPXROOT 10 29 Oct 12 2021 onetstat -> ../usr/lpp/tcpip/bin/onetstat

new-exp.tests fails with string manipulation

Running the test 'by hand' it seems to work ok, but running in the harness, it gets truncated.
The particular failing test is in new-exp8.sub:

declare z="start"
declare NUM=1000
pat1='str'
export LINE_MAX=100
#----------------------------------
# create a long string with ';'
#----------------------------------
for ((i=0; i<$NUM; i++)); do
    z="$z;string$i"
done

#z="$z;string;foo"

#------------------------------
# delete everything except ';'
#------------------------------

# try different patterns here
x="${z//$pat1}"
echo $x

The string being echo'ed is getting truncated

Process substitution with bash 5.2.0 (Build 551)

bash 5.2.0 (Build 551) (bash-5.2.20230215_173052.zos.pax.Z)

look like process substitution is not yielding proper results

RC=(0) [SYSD] bash-5.2$ echo <(date)
/u/@02858/tmp/sh-np.DhdCxQ

RC=(0) [SYSD] bash-5.2$ cat <(date)
▒▒̀▒▒�▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒RC=(0) [SYSD] bash-5.2$

RC=(0) [SYSD] bash-5.2$ wc -l <(ssh l98misdb491 "cat *Yum")
0 /u/@02858/tmp/sh-np.gbAaxQ

--

Expecting something like this

$ echo <(date)
/dev/fd63

$ cat <(date)
Thu Feb 16 13:29:25 CST 2023

$ wc -l <(ssh l98misdb491 "cat *Yum")
4 /dev/fd63

#! used with script as command does not work.

I have 2 scripts in /home/knacke/tmp, a.sh and b.sh .
a.sh:

#!/home/knacke/tmp/b.sh
echo "in a"
echo "$@"

b.sh:

#!/bin/sh
echo "in b"
echo "$@"

Now let's run a.sh. On Linux I get

in b
./a.sh

as output but on z/OS I get

in a

I believe that is caused by a special feature of some of the exec functions (see the docs):

Special behavior for XPG4: If this file is not a valid executable object, the execlp() and execvp() functions invoke /bin/sh with the invoker's path name and the rest of the input arguments.

I am quite sure that bash does not use execlp() or execvp(), and I think that this is the reason why this case does not work.
The practical implication of this is e.g. when you create a wrapper script to call python, and use that name as command on the #! line then it does not work.

Bash garbling output after stderr to stdout redirection and then piping to tee

Here's a reduced scenario:
a.sh:

#!/bin/sh
echo "blabla" >&2
echo "blabla" >&2

The output is garbled:

$ ./a.sh 2>&1 | tee a.txt
blabla
�%/�%/�
$ _TAG_REDIR_OUT= ./a.sh 2>&1 | tee a.txt
blabla
blabla

Works when _TAG_REDIR_OUT is unset as above

There might be some double conversion happening due to _TAG_REDIR_OUT=txt and bash tagging stdout

history.test fails due to cat producing different results

history.output should be empty but has the following (unprintable) stuff in it:

�[0m����[0;34m~C�[0m���k����[0;34m^U�[0mL@echo cc
�[0;34m~E~C~H~V�[0m@�[0;34m~C~C^U�[0m```�[0;34m^U�[0mn@�[0;34m~E~C~H~V�[0m@�[0;34m~C~C^U�[0mn@�[0;34m~E~C~H~V�[0m@�[0;34m~C~C^U�[0m����[0;34m~C�[0m���k����[0;34m^U�[0mL@echo cc
�[0;34m~E~C~H~V�[0m@�[0;34m~C~C^U�[0m```�[0;34m^U�[0mn@�[0;34m~E~C~H~V�[0m@�[0;34m~C~C^U�[0mn@�[0;34m~E~C~H~V�[0m@�[0;34m~C~C^U

If I tag the file as EBCDIC, I get:

�[0;33m114c114,115�[0m
�[0;35m< ���?�[0;34m~@�[0;35m���[0;34m~N�[0;35mecho cc�[0m
�[0;33m---�[0m
�[0;36m> echo cc�[0m
�[0;36m> echo cc�[0m
�[0;33m119c120,121�[0m
�[0;35m< ���?�[0;34m~@�[0;35m���[0;34m~N�[0;35mecho cc�[0m
�[0;33m---�[0m
�[0;36m> echo cc�[0m
�[0;36m> echo cc

This EBCDIC muck is likely because I am not using the diffutils.

But there is still an issue with the unprintable text coming out in a different spot in the two diffs.

In history.tests the code does:

# these two blocks had better both result in the same output
echo aa
echo bb
echo cc
fc -e cat

echo aa
echo bb
echo cc
fc -e cat -1

They are not exactly the same when traced:

+ echo cc
cc
+ fc -e cat
++ cat /tmp/bash-fc.HcgCxQ
echo cc
echo cc
++ echo cc
cc
+ echo aa
aa
+ echo bb
bb
+ echo cc
cc
+ fc -e cat -1
++ cat /tmp/bash-fc.fCgaxQ
echo cc
echo cc
++ echo cc
cc

Running using the Rocket bash I get an LE dump:

    1     CEEHDSP     +00004B12              CEEPLPKA             CEEHDSP                        UI78103  Call
    2     CEEHRNUH    +0000009A              CEEPLPKA             CEEHRNUH                       HLE77C0  Call
    3     __fprintf_a +00000820              CELHV003                                            HLE77C0  Exception
    4     fc_builtin  +000009F8              bash                                                         Call
    5     execute_builtin
                      +000003BE              bash                                                         Call
    6     execute_builtin_or_function
                      +00000166              bash                                                         Call
    7     execute_simple_command
                      +00000AB2              bash                                                         Call
    8     execute_command_internal
                      +000008E6              bash                                                         Call
    9     execute_command
                      +0000008C              bash                                                         Call
    10    reader_loop +00000284              bash                                                         Call
    11    main        +00000C3A              bash                                                         Call
    12    CEEVROND    +0000127C              CEEPLPKA                                                     Call
    13    EDCZHINV    +000000B4              CELHV003             EDCZHINV                       HLE77C0  Call
    14    CEEBBEXT    +000001C6              CEEPLPKA             CEEBBEXT                       HLE77C0  Call

A question about bash pipe(|)

I have an input file which is untagged and its content is ascii characters "abc".
$ echo abc >input
$ chtag -r input
$ chtag -p input

  • untagged T=off input
    And I have a Go program named main which reads data from stdin and prints the data in hex.
    $ cat input | main
    input is: 2fefbfbdc48e

I expected got "6162630a" which is "abc\n" in hex. It seems bash does a conversation from 819 to 1047. On my test system, _BPXK_AUTOCVT is seI have t to "On". I am confused about the behavior. Any thought?
If the input file is tagged with 819 I got the expected output.
$ chtag -p input
6162630a

bash source code does not build on z/OS

First failure:

xlclang -c  -DHAVE_CONFIG_H -DSHELL  -I. -I..  -I.. -I../include -I../lib -I. -I../lib/intl -I/fultonm/zopen/dev/bashport/bash-5.2-rc4/lib/intl   -DNSIG=9 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE -D_OPEN_SYS_FILE_EXT=1 -D_AE_BIMODAL=1 -D_ENHANCED_ASCII_EXT=0xFFFFFFFF  -qascii -std=gnu11   mkbuiltins.c
./mkbuiltins.c:201:12: error: static declaration of 'rename' follows non-static declaration
static int rename ();
           ^

heredoc test fails with comparison

The test can be reduced to:

cd  ~/zopen/dev/bashport/bash-5.2/tests
catfile()
{
   cat <<- EOF > $FILENAME
     $(cat $1)
EOF
  cmp $FILENAME $1
 # rm -f $FILENAME
 }

catfle ../y.tab.c

This fails.

bash <() seems to treat data as 1047

In the bash shell, run the following using the 'coreutils' diff (which has the -u capability)

echo "Hello" >hw.txt
diff -u <(sed -e 's/H/J/' hw.txt) <(cat hw.txt)
--- /tmp/sh-np.ddhFxQ	2022-11-25 18:33:28 +0000
+++ /tmp/sh-np.haaHxQ	2022-11-25 18:33:28 +0000
@@ -1 +1 @@
-х���
\ No newline at end of file
+ȅ���
\ No newline at end of file

Compare this to running with the 'standard' /bin/diff and you get:

/bin/diff <(sed -e 's/H/J/' hw.txt) <(cat hw.txt)
1c1
< Jello
---
> Hello

which could indicate the temp files are both untagged (and treated as 1047)

Remove setting _CEE_RUNOPTS, _TAG_REDIR_IN etc from .env

The .env file is defining:

  • _TAG_REDIR_IN
  • _TAG_REDIR_ERR
  • _TAG_REDIR_OUT
  • _CEE_RUNOPTS

The .env file should not be defining any environment variables that is a user preference. It can update PATH etc because those are needed to run bash. It should not be make personal preferences for users.

I noticed this because switching from our current bash to this bash changed the behaviour of our scripts.

Process substitution issues when using /dev/fd

z/OS offers both /dev/fdN and /dev/fd/N. It seems that on some systems, /dev/fd is a character device and in others it's a directory. Bash assumes it is always a directory, so this can introduce problems on systems where it's a character device.

Another issue is that the character devices are untagged and as such there is no autoconversion.

exp.tests fails

The sequence that causes the issue is:

var=$'x\001y\177z'

recho "$var"
recho $var

declare -p var
recho $(declare -p var)

echo "var=$var" | sed -n l
echo "declare -- var=\"$var\"" | sed -n l

in exp8.sub
Specifically:

echo "declare -- var=\"$var\"" | sed -n l

prints out:

echo "declare -- var=\"$var\"" | sed -n l
var=x\001y\007z$
declare -- var="x\001y\007z"$

using the default 'sed' but prints out:

echo "var=$var" | sed -n l
var=x\001y\177z$

with the z/os community sed.

Adding 'sed' to the list of required tools for bashport

builtins.tests fails

The problem is that:

if [  -e /dev/stdin ]; then
 ...
else
 ...
fi

is taking the 'true' path even though /dev/stdin does not exist.
This works for the default 'sh' and fails with the Rocket port of bash as well.

posixpat.tests causes protection exception

When run by hand:

case "abc" in
[[:alpha:]][[=b=]][[:ascii:]])  echo ok 1;;
esac
CEE3204S The system detected a protection exception (System Completion Code=0C4).
         From entry point brackmatch at compile unit offset +0000000026A7B9EE at entry offset +0000000000000506 at address 0000000026A7B9EE.
Segmentation fault

Subsequent runs 'worked' ok (so inconsistent protection exception)

I didn't get a dump but I have another one here that I think is the same:

  Traceback:
    DSA   Entry       E  Offset  Statement   Load Mod             Program Unit                   Service  Status
    1     CEEHDSP     +00003FD8              CELQLIB              CEEHDSP                        UI78103  Call
    2     CEEOSIGJ    +00000962              CELQLIB              CEEOSIGJ                       HLE77C0  Call
    3     CELQHROD    +00000266              CELQLIB              CELQHROD                       HLE77C0  Call
    4     CEEOSIGG    -1EDD81B0              CELQLIB              CEEOSIGG                       UI75815  Call
    5     CELQHROD    +00000266              CELQLIB              CELQHROD                       HLE77C0  Call
    6     collequiv   +0000014A              CELQLIB                                             HLE77C0  Exception
    7     brackmatch  +00000506              bash                                                         Call
    8     gmatch      +00001CE4              bash                                                         Call
    9     internal_strmatch
                      +000000DC              bash                                                         Call
    10    xstrmatch   +0000005E              bash                                                         Call
    11    strmatch    +00000070              bash                                                         Call
    12    execute_case_command
                      +000005A8              bash                                                         Call
    13    execute_command_internal
                      +000016B6              bash                                                         Call
    14    execute_command
                      +000000AC              bash                                                         Call
    15    reader_loop +0000056C              bash                                                         Call
    16    main        +00001910              bash                                                         Call
    17    CELQINIT    +00001ACA              CELQLIB              CELQINIT                       HLE77C0  Call

trap.tests loops through sigspec in a different order than expected

On z/OS:

trap 'echo aborting' HUP INT QUIT ABRT TERM
trap

prints out:

trap -- 'echo exiting' EXIT
trap -- 'echo aborting' SIGHUP
trap -- 'echo aborting' SIGINT
trap -- 'echo aborting' SIGABRT
trap -- 'echo aborting' SIGTERM
trap -- 'echo aborting' SIGQUIT
trap -- '' 27

On the Mac with bash (and in expected results):

trap -- 'echo aborting' SIGHUP
trap -- 'echo aborting' SIGINT
trap -- 'echo aborting' SIGQUIT
trap -- 'echo aborting' SIGABRT
trap -- 'echo aborting' SIGTERM

This is probably because the output is ordered by number and SIGQUIT is 24 on z/OS but 3 on the Mac.

Bash does not source users bashrc file when started by non-interactive ssh command

When bash is started by the sshd daemon to run a non-interactive command, the ~/.bashrc script is not loaded.

Steps to Reproduce

  1. Set ZOSOpenTools bash as standard shell in OMVS segment
  2. Run ssh command non-interactively (e.g. ssh [host] -- "env")
  3. See that environment is missing required variables

Expected Behavior

Bash should source the bashrc file, even in an non-interactive session, when called by sshd or other remote daemons.
See "Invoked by remote shell daemon" in section 6.2 of the bash manual (https://www.gnu.org/software/bash/manual/bash.html#Bash-Startup-Files).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.